From 71a2581b8fb9e8b3c9f3f18d277c4620e265c6c4 Mon Sep 17 00:00:00 2001 From: Andrea Di Cesare Date: Mon, 7 Aug 2023 16:38:17 +0200 Subject: [PATCH] :recycle: Refactor MetricNameAndLabels and MetricLabel to improve metrics collection performance --- .../org/restheart/metrics/MetricLabel.java | 27 +++++----- .../metrics/MetricNameAndLabels.java | 49 +++++++------------ .../java/{logback-test.xml => logback.xml} | 0 .../restheart/metrics/MetricsNamesTest.java | 8 ++- .../metrics/RHDropwizardExports.java | 3 +- .../metrics/RequestsMetricsCollector.java | 7 +-- restheart.code-workspace | 3 +- 7 files changed, 38 insertions(+), 59 deletions(-) rename commons/src/test/java/{logback-test.xml => logback.xml} (100%) diff --git a/commons/src/main/java/org/restheart/metrics/MetricLabel.java b/commons/src/main/java/org/restheart/metrics/MetricLabel.java index 888a15567..7e8051dcc 100644 --- a/commons/src/main/java/org/restheart/metrics/MetricLabel.java +++ b/commons/src/main/java/org/restheart/metrics/MetricLabel.java @@ -20,12 +20,8 @@ package org.restheart.metrics; -import java.util.ArrayDeque; -import java.util.Deque; -import org.bson.BsonDocument; -import org.bson.json.JsonWriterSettings; -import org.restheart.utils.BsonUtils; -import static org.restheart.utils.BsonUtils.document; +import java.util.ArrayList; +import java.util.List; /** * record for metric labels that can be serialized/deserialized to/from string @@ -33,26 +29,25 @@ * @author Andrea Di Cesare {@literal } */ public record MetricLabel(String name, String value) { - private static JsonWriterSettings jsonWriterSettings = JsonWriterSettings.builder().indent(false).build(); + public static String SEPARATOR = "="; - public BsonDocument bson() { - return document().put("n", name).put("v", value).get(); + public MetricLabel(String name, String value) { + this.name = name.replaceAll("=", "_").replaceAll("\\.", "_"); + this.value = value.replaceAll("\\.", "_"); } - public static MetricLabel fromJson(BsonDocument raw) { - return new MetricLabel(raw.getString("n").getValue(), raw.getString("v").getValue()); - } public String toString() { - return BsonUtils.minify(bson().toJson(jsonWriterSettings)); + return name.concat(SEPARATOR).concat(value); } public static MetricLabel from(String raw) { - return fromJson(BsonUtils.parse(raw).asDocument()); + var sepIdx = raw.indexOf(SEPARATOR); + return new MetricLabel(raw.substring(0, sepIdx), raw.substring(sepIdx+1)); } - public static Deque from(MetricLabel... labels) { - var ret = new ArrayDeque(); + public static List collect(MetricLabel... labels) { + var ret = new ArrayList(); for (var label: labels) { ret.add(label); } diff --git a/commons/src/main/java/org/restheart/metrics/MetricNameAndLabels.java b/commons/src/main/java/org/restheart/metrics/MetricNameAndLabels.java index 9d232f63f..256287265 100644 --- a/commons/src/main/java/org/restheart/metrics/MetricNameAndLabels.java +++ b/commons/src/main/java/org/restheart/metrics/MetricNameAndLabels.java @@ -19,51 +19,40 @@ */ package org.restheart.metrics; -import org.bson.BsonDocument; -import org.bson.json.JsonWriterSettings; -import org.restheart.utils.BsonUtils; - -import static org.restheart.utils.BsonUtils.document; - -import java.util.ArrayDeque; -import java.util.Deque; +import java.util.Arrays; +import java.util.List; import java.util.stream.Collectors; -import static org.restheart.utils.BsonUtils.array; - /** * record for metric name and labels that can be serialized/deserialized to/from string * * @author Andrea Di Cesare {@literal } */ -public record MetricNameAndLabels(String name, Deque lables) { - private static JsonWriterSettings jsonWriterSettings = JsonWriterSettings.builder().indent(false).build(); - - public BsonDocument bson() { - var _labels = array(); - var ret = document().put("l", _labels).put("n", name()); +public record MetricNameAndLabels(String name, List lables) { + public static String SEPARATOR = "."; + private static String SEPARATOR_REGEX = "\\."; - lables().stream().map(MetricLabel::bson).forEachOrdered(_labels::add); - - return ret.get(); + public MetricNameAndLabels(String name, List lables) { + this.name = name.replaceAll("SEPARATOR_REGEX", "_"); + this.lables = lables; } - public static MetricNameAndLabels fromJson(BsonDocument raw) { - var _labels = raw.getArray("l").stream() - .map(v -> v.asDocument()) - .map(d -> MetricLabel.fromJson(d)) - .collect(Collectors.toList()); + public static MetricNameAndLabels from(String raw) { + var name = raw.substring(0, raw.indexOf(".")); - var labels = new ArrayDeque(_labels); + var labels = Arrays.stream(raw.split(SEPARATOR_REGEX)) + .skip(1) + .map(l -> MetricLabel.from(l)) + .collect(Collectors.toList()); - return new MetricNameAndLabels(raw.getString("n").getValue(), labels); + return new MetricNameAndLabels(name, labels); } public String toString() { - return BsonUtils.minify(bson().toJson(jsonWriterSettings)); - } + var sb = new StringBuilder(); + sb.append(name).append(SEPARATOR); - public static MetricNameAndLabels fromString(String raw) { - return fromJson(BsonUtils.parse(raw).asDocument()); + sb.append(lables.stream().map(l -> l.toString()).collect(Collectors.joining(SEPARATOR))); + return sb.toString(); } } diff --git a/commons/src/test/java/logback-test.xml b/commons/src/test/java/logback.xml similarity index 100% rename from commons/src/test/java/logback-test.xml rename to commons/src/test/java/logback.xml diff --git a/commons/src/test/java/org/restheart/metrics/MetricsNamesTest.java b/commons/src/test/java/org/restheart/metrics/MetricsNamesTest.java index 7a8b10e0b..5bcdea888 100644 --- a/commons/src/test/java/org/restheart/metrics/MetricsNamesTest.java +++ b/commons/src/test/java/org/restheart/metrics/MetricsNamesTest.java @@ -23,8 +23,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import java.util.ArrayDeque; +import java.util.ArrayList; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -47,7 +46,7 @@ public void testMetricLabelSerialization() { @Test public void testMetricNameAndLabelsSerialization() { - var labels = new ArrayDeque(); + var labels = new ArrayList(); labels.add(new MetricLabel("method", "GET")); labels.add(new MetricLabel("status", "200")); @@ -56,9 +55,8 @@ public void testMetricNameAndLabelsSerialization() { var nameAndLabelsAsString = nameAndLabelsFromConstructor.toString(); LOG.debug("string representation {}", nameAndLabelsAsString); - LOG.debug("toString representation {}", nameAndLabelsFromConstructor); - var nameAndLabelsFromString = MetricNameAndLabels.fromString(nameAndLabelsAsString); + var nameAndLabelsFromString = MetricNameAndLabels.from(nameAndLabelsAsString); assertEquals(nameAndLabelsFromConstructor, nameAndLabelsFromString); } diff --git a/metrics/src/main/java/org/restheart/metrics/RHDropwizardExports.java b/metrics/src/main/java/org/restheart/metrics/RHDropwizardExports.java index 8c2260034..bf8f165a4 100644 --- a/metrics/src/main/java/org/restheart/metrics/RHDropwizardExports.java +++ b/metrics/src/main/java/org/restheart/metrics/RHDropwizardExports.java @@ -13,7 +13,6 @@ import io.prometheus.client.dropwizard.samplebuilder.SampleBuilder; import io.prometheus.client.Collector.MetricFamilySamples.Sample; import io.prometheus.client.dropwizard.samplebuilder.DefaultSampleBuilder; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -206,7 +205,7 @@ public Sample createSample(String dropwizardName, String nameSuffix, List(); var _additionalLabelValues = new ArrayList(); diff --git a/metrics/src/main/java/org/restheart/metrics/RequestsMetricsCollector.java b/metrics/src/main/java/org/restheart/metrics/RequestsMetricsCollector.java index 723b2fd57..aadd36baa 100644 --- a/metrics/src/main/java/org/restheart/metrics/RequestsMetricsCollector.java +++ b/metrics/src/main/java/org/restheart/metrics/RequestsMetricsCollector.java @@ -35,10 +35,7 @@ import static org.restheart.metrics.MetricsService.METRICS_REGISTRIES_PREFIX; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import com.codahale.metrics.SharedMetricRegistries; - -import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -167,8 +164,8 @@ private void addMetrics(PathMatchResult pathTemplate, long startTime, S .map(param -> new MetricLabel("path_template_param_".concat(param.getKey()), param.getValue())) .collect(Collectors.toList()); - var t1wp = new ArrayDeque(); - t1wp.addAll(MetricLabel.from(method, matchedTemplate, status)); + var t1wp = new ArrayList(); + t1wp.addAll(MetricLabel.collect(method, matchedTemplate, status)); t1wp.addAll(matchParams); // custom labels diff --git a/restheart.code-workspace b/restheart.code-workspace index 480a89d4c..b08df1f01 100644 --- a/restheart.code-workspace +++ b/restheart.code-workspace @@ -43,7 +43,8 @@ "**/bin", "**/archetype-resources" ], - "java.compile.nullAnalysis.mode": "disabled" + "java.compile.nullAnalysis.mode": "disabled", + "java.debug.settings.onBuildFailureProceed": true }, "launch": { "version": "0.2.0",