From fb3f3c52cf3d6190e4ccd2d0e2ee84480e0261ec Mon Sep 17 00:00:00 2001 From: Peter Paul Bakker Date: Mon, 7 Mar 2022 10:55:44 +0100 Subject: [PATCH 1/2] Tweak performance for Prometheus scraping endpoint Reduce the number of times capacity growth is needed inside the StringWriter. A typical default SpringBoot Prometheus page has more than 11k characters. Best performance results when no capacity growth is needed at all, so base it on previous metrics page size plus some room for possible extra metric info. See gh-30085 --- .../export/prometheus/PrometheusScrapeEndpoint.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpoint.java index eb179c543842..46974bab0cf6 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpoint.java @@ -42,8 +42,12 @@ @WebEndpoint(id = "prometheus") public class PrometheusScrapeEndpoint { + private static final int METRICS_SCRAPE_CHARS_EXTRA = 1024; + private final CollectorRegistry collectorRegistry; + private volatile int nextMetricsScrapeSize = 16; + public PrometheusScrapeEndpoint(CollectorRegistry collectorRegistry) { this.collectorRegistry = collectorRegistry; } @@ -51,12 +55,16 @@ public PrometheusScrapeEndpoint(CollectorRegistry collectorRegistry) { @ReadOperation(producesFrom = TextOutputFormat.class) public WebEndpointResponse scrape(TextOutputFormat format, @Nullable Set includedNames) { try { - Writer writer = new StringWriter(); + Writer writer = new StringWriter(nextMetricsScrapeSize); Enumeration samples = (includedNames != null) ? this.collectorRegistry.filteredMetricFamilySamples(includedNames) : this.collectorRegistry.metricFamilySamples(); format.write(writer, samples); - return new WebEndpointResponse<>(writer.toString(), format); + + String scrapePage = writer.toString(); + nextMetricsScrapeSize = scrapePage.length() + METRICS_SCRAPE_CHARS_EXTRA; + + return new WebEndpointResponse<>(scrapePage, format); } catch (IOException ex) { // This actually never happens since StringWriter doesn't throw an IOException From d14980ed5e1e9a0bf136bd9fec085c94d94463a3 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 9 Mar 2022 12:08:55 +0100 Subject: [PATCH 2/2] Polish "Tweak performance for Prometheus scraping endpoint" See gh-30085 --- .../metrics/export/prometheus/PrometheusScrapeEndpoint.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpoint.java index 46974bab0cf6..89cc2822d3e0 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpoint.java @@ -55,14 +55,14 @@ public PrometheusScrapeEndpoint(CollectorRegistry collectorRegistry) { @ReadOperation(producesFrom = TextOutputFormat.class) public WebEndpointResponse scrape(TextOutputFormat format, @Nullable Set includedNames) { try { - Writer writer = new StringWriter(nextMetricsScrapeSize); + Writer writer = new StringWriter(this.nextMetricsScrapeSize); Enumeration samples = (includedNames != null) ? this.collectorRegistry.filteredMetricFamilySamples(includedNames) : this.collectorRegistry.metricFamilySamples(); format.write(writer, samples); String scrapePage = writer.toString(); - nextMetricsScrapeSize = scrapePage.length() + METRICS_SCRAPE_CHARS_EXTRA; + this.nextMetricsScrapeSize = scrapePage.length() + METRICS_SCRAPE_CHARS_EXTRA; return new WebEndpointResponse<>(scrapePage, format); }