Skip to content

Commit

Permalink
♻️ Refactor MetricNameAndLabels and MetricLabel to improve metrics co…
Browse files Browse the repository at this point in the history
…llection performance
  • Loading branch information
ujibang committed Aug 7, 2023
1 parent 89ac724 commit 71a2581
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 59 deletions.
27 changes: 11 additions & 16 deletions commons/src/main/java/org/restheart/metrics/MetricLabel.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,34 @@

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
*
* @author Andrea Di Cesare {@literal <[email protected]>}
*/
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<MetricLabel> from(MetricLabel... labels) {
var ret = new ArrayDeque<MetricLabel>();
public static List<MetricLabel> collect(MetricLabel... labels) {
var ret = new ArrayList<MetricLabel>();
for (var label: labels) {
ret.add(label);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <[email protected]>}
*/
public record MetricNameAndLabels(String name, Deque<MetricLabel> 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<MetricLabel> 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<MetricLabel> 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<MetricLabel>(_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();
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -47,7 +46,7 @@ public void testMetricLabelSerialization() {

@Test
public void testMetricNameAndLabelsSerialization() {
var labels = new ArrayDeque<MetricLabel>();
var labels = new ArrayList<MetricLabel>();
labels.add(new MetricLabel("method", "GET"));
labels.add(new MetricLabel("status", "200"));

Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -206,7 +205,7 @@ public Sample createSample(String dropwizardName, String nameSuffix, List<String
if (dropwizardName.startsWith("jvm")) {
return DSB.createSample(dropwizardName, nameSuffix, additionalLabelNames, additionalLabelValues, value);
} else {
var nals = MetricNameAndLabels.fromString(dropwizardName);
var nals = MetricNameAndLabels.from(dropwizardName);

var _additionalLabelNames = new ArrayList<String>();
var _additionalLabelValues = new ArrayList<String>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -167,8 +164,8 @@ private void addMetrics(PathMatchResult<Boolean> pathTemplate, long startTime, S
.map(param -> new MetricLabel("path_template_param_".concat(param.getKey()), param.getValue()))
.collect(Collectors.toList());

var t1wp = new ArrayDeque<MetricLabel>();
t1wp.addAll(MetricLabel.from(method, matchedTemplate, status));
var t1wp = new ArrayList<MetricLabel>();
t1wp.addAll(MetricLabel.collect(method, matchedTemplate, status));
t1wp.addAll(matchParams);

// custom labels
Expand Down
3 changes: 2 additions & 1 deletion restheart.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit 71a2581

Please sign in to comment.