aboutsummaryrefslogtreecommitdiffstats
path: root/metrics-proxy
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2021-12-16 21:26:32 +0100
committerHenning Baldersheim <balder@yahoo-inc.com>2021-12-16 21:26:32 +0100
commit47dab19f0e4ab17e501e26f82d2ce443406d3155 (patch)
treecf99a2e39394b3e9409a30217aac674a411ec4d2 /metrics-proxy
parent7f04f3a850619c73ea25aab853ff7ec1ea71e707 (diff)
Avoid creating a temporary YamasArrayJsonModel which contains a copy of the MetricsPacket list that is used just for simple json printing with an ObjectMapper.
Insteda do it the old school by genrating the json with the core api which is streaming.
Diffstat (limited to 'metrics-proxy')
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasHandler.java2
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasResponse.java16
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java19
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasArrayJsonModel.java54
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModel.java1
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java152
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcServer.java12
-rw-r--r--metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java25
-rw-r--r--metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java76
-rw-r--r--metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java2
10 files changed, 173 insertions, 186 deletions
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasHandler.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasHandler.java
index 822f4e0b5d5..10b3cc3077b 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasHandler.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasHandler.java
@@ -61,7 +61,7 @@ public class YamasHandler extends HttpHandlerBase {
try {
List<MetricsPacket> metrics = consumer == null ? valuesFetcher.fetchAllMetrics() : valuesFetcher.fetch(consumer);
metrics.addAll(nodeMetricGatherer.gatherMetrics()); // TODO: Currently only add these metrics in this handler. Eventually should be included in all handlers
- return new YamasResponse(OK, YamasJsonUtil.toYamasArray(metrics, true));
+ return new YamasResponse(OK, metrics);
} catch (JsonRenderingException e) {
return new ErrorResponse(INTERNAL_SERVER_ERROR, e.getMessage());
}
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasResponse.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasResponse.java
index 23b56e94ae4..49f5036b3fd 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasResponse.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasResponse.java
@@ -1,24 +1,25 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package ai.vespa.metricsproxy.http.yamas;
-import ai.vespa.metricsproxy.metric.model.json.JacksonUtil;
-import ai.vespa.metricsproxy.metric.model.json.YamasArrayJsonModel;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import ai.vespa.metricsproxy.metric.model.MetricsPacket;
+import ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil;
import com.yahoo.container.jdisc.HttpResponse;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.List;
+
/**
* @author olaa
*/
public class YamasResponse extends HttpResponse {
- private final YamasArrayJsonModel data;
+ private final List<MetricsPacket> metrics;
- public YamasResponse(int code, YamasArrayJsonModel data) {
+ public YamasResponse(int code, List<MetricsPacket> metrics) {
super(code);
- this.data = data;
+ this.metrics = metrics;
}
@Override
@@ -28,8 +29,7 @@ public class YamasResponse extends HttpResponse {
@Override
public void render(OutputStream outputStream) throws IOException {
- ObjectMapper mapper = JacksonUtil.createObjectMapper();
- mapper.writeValue(outputStream, data);
+ YamasJsonUtil.toJson(metrics, outputStream, true);
}
}
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java
index 4ac2cc4dec8..c4f2b7198a4 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java
@@ -19,6 +19,12 @@ import java.util.Locale;
*/
public class JacksonUtil {
+ private static final DecimalFormat decimalFormat = createDecimalFormat();
+ private static DecimalFormat createDecimalFormat() {
+ DecimalFormat df = new DecimalFormat("#.####", new DecimalFormatSymbols(Locale.ENGLISH));
+ df.setMaximumFractionDigits(13);
+ return df;
+ }
/**
* Returns an object mapper with a custom floating point serializer to avoid scientific notation
*/
@@ -30,14 +36,17 @@ public class JacksonUtil {
mapper.registerModule(module);
return mapper;
}
+ /**
+ * Returns an object mapper with a custom floating point serializer to avoid scientific notation
+ */
+ public static void writeDouble(JsonGenerator jgen, Double value) throws IOException {
+ jgen.writeNumber(decimalFormat.format(value));
+ }
public static class DoubleSerializer extends JsonSerializer<Double> {
@Override
- public void serialize(Double value, JsonGenerator jgen,
- SerializerProvider provider) throws IOException {
- DecimalFormat df = new DecimalFormat("#.####", new DecimalFormatSymbols(Locale.ENGLISH));
- df.setMaximumFractionDigits(13);
- jgen.writeNumber(df.format(value));
+ public void serialize(Double value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
+ writeDouble(jgen, value);
}
}
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasArrayJsonModel.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasArrayJsonModel.java
deleted file mode 100644
index 539e3b851ae..00000000000
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasArrayJsonModel.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package ai.vespa.metricsproxy.metric.model.json;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Datamodel for the metricsproxy representation of multiple yamas checks.
- */
-@JsonIgnoreProperties(ignoreUnknown = true)
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class YamasArrayJsonModel {
- @JsonProperty("metrics")
- public final List<YamasJsonModel> metrics = new ArrayList<>();
-
- public void add(List<YamasJsonModel> results) {
- metrics.addAll(results);
- }
-
- public void add(YamasJsonModel result) {
- metrics.add(result);
- }
-
- public void add(YamasArrayJsonModel array) {
- metrics.addAll(array.metrics);
- }
-
- /**
- * Convenience method to serialize.
- * <p>
- * Custom floating point serializer to avoid scientifc notation
- *
- * @return Serialized json
- */
- public String serialize() {
- ObjectMapper mapper = JacksonUtil.createObjectMapper();
-
- if (metrics.size() > 0) {
- try {
- return mapper.writeValueAsString(this);
- } catch (JsonProcessingException e) {
- e.printStackTrace();
- }
- }
- return "{}"; // Backwards compatibility
- }
-
-}
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModel.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModel.java
index d2be7be25d1..911c772c0e4 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModel.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModel.java
@@ -10,7 +10,6 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java
index 602879aa0b6..b5b8e30a218 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java
@@ -5,21 +5,21 @@ import ai.vespa.metricsproxy.metric.model.ConsumerId;
import ai.vespa.metricsproxy.metric.model.MetricsPacket;
import ai.vespa.metricsproxy.metric.model.ServiceId;
import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.StreamWriteFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.yahoo.concurrent.CopyOnWriteHashMap;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import static ai.vespa.metricsproxy.http.ValuesFetcher.defaultMetricsConsumerId;
-import static com.yahoo.stream.CustomCollectors.toLinkedMap;
import static java.util.Collections.emptyList;
import static java.util.logging.Level.WARNING;
@@ -28,10 +28,12 @@ import static java.util.logging.Level.WARNING;
*/
public class YamasJsonUtil {
private static final Logger log = Logger.getLogger(YamasJsonUtil.class.getName());
+ private static final JsonFactory factory = JsonFactory.builder()
+ .enable(StreamWriteFeature.WRITE_BIGDECIMAL_AS_PLAIN)
+ .build();
static final String YAMAS_ROUTING = "yamas";
- private static final Map<Set<ConsumerId>, Map<String, YamasJsonModel.YamasJsonNamespace>> globalNameSpaces = new CopyOnWriteHashMap<>();
public static MetricsPacket.Builder toMetricsPacketBuilder(YamasJsonModel jsonModel) {
if (jsonModel.application == null)
throw new IllegalArgumentException("Service id cannot be null");
@@ -45,21 +47,6 @@ public class YamasJsonUtil {
.addConsumers(jsonModel.getYamasConsumers());
}
- public static YamasArrayJsonModel toYamasArray(Collection<MetricsPacket> metricsPackets) {
- YamasArrayJsonModel yamasArray = toYamasArray(metricsPackets, false);
-
- // Add a single status object at the end
- yamasArray.metrics.stream().findFirst().map(YamasJsonModel::getYamasConsumers)
- .ifPresent(consumers -> yamasArray.add(getStatusYamasModel("Data collected successfully", 0, consumers)));
- return yamasArray;
- }
-
- public static YamasArrayJsonModel toYamasArray(Collection<MetricsPacket> metricsPackets, boolean addStatus) {
- YamasArrayJsonModel yamasArray = new YamasArrayJsonModel();
- metricsPackets.forEach(packet -> yamasArray.add(toYamasModel(packet, addStatus)));
- return yamasArray;
- }
-
/**
* Converts the given json formatted string to a list of metrics packet builders.
* Note that this method returns an empty list if an IOException occurs,
@@ -81,58 +68,91 @@ public class YamasJsonUtil {
}
}
- private static YamasJsonModel getStatusYamasModel(String statusMessage, int statusCode, Set<ConsumerId> consumers) {
- YamasJsonModel model = new YamasJsonModel();
- model.status_code = statusCode;
- model.status_msg = statusMessage;
- model.application = "yms_check_vespa";
- model.routing = computeIfAbsent(consumers);
- return model;
+ public static List<MetricsPacket> appendOptionalStatusPacket(List<MetricsPacket> packets) {
+ if (packets.isEmpty()) return packets;
+
+ Set<ConsumerId> consumers = extractSetForRouting(packets.get(0).consumers());
+ if (consumers.isEmpty()) return packets;
+ List<MetricsPacket> withStatus = new ArrayList<>(packets);
+ withStatus.add(new MetricsPacket.Builder(ServiceId.toServiceId("yms_check_vespa"))
+ .statusCode(0)
+ .statusMessage("Data collected successfully")
+ .addConsumers(consumers).build());
+ return withStatus;
}
- private static YamasJsonModel toYamasModel(MetricsPacket packet, boolean addStatus) {
- YamasJsonModel model = new YamasJsonModel();
-
- if (addStatus) {
- model.status_code = packet.statusCode;
- model.status_msg = packet.statusMessage;
+ public static String toJson(List<MetricsPacket> metrics, boolean addStatus) {
+ try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
+ toJson(metrics, output, addStatus);
+ output.flush();
+ return output.toString();
+ } catch (IOException e) {
+ return "{}";
}
-
- model.application = packet.service.id;
- model.timestamp = (packet.timestamp == 0L) ? null : packet.timestamp;
-
- model.metrics = (packet.metrics().isEmpty())
- ? null
- : packet.metrics().entrySet().stream().collect(
- toLinkedMap(id2metric -> id2metric.getKey().id,
- id2metric -> id2metric.getValue().doubleValue()));
-
- model.dimensions = (packet.dimensions().isEmpty())
- ? null
- : packet.dimensions().entrySet()
- .stream()
- .filter(entry -> entry.getKey() != null && entry.getValue() != null)
- .collect(toLinkedMap(id2dim -> id2dim.getKey().id, Map.Entry::getValue));
-
- model.routing = computeIfAbsent(packet.consumers());
-
- return model;
}
-
- private static Map<String, YamasJsonModel.YamasJsonNamespace> computeIfAbsent(Set<ConsumerId> consumers) {
- return globalNameSpaces.computeIfAbsent(consumers, YamasJsonUtil::createYamasJson);
+ private static Set<ConsumerId> extractSetForRouting(Set<ConsumerId> consumers) {
+ return consumers.stream()
+ .filter(consumerId -> consumerId != defaultMetricsConsumerId)
+ .collect(Collectors.toSet());
+ }
+ public static void toJson(List<MetricsPacket> metrics, OutputStream outputStream, boolean addStatus) throws IOException {
+ JsonGenerator generator = factory.createGenerator(outputStream);
+ generator.writeStartObject();
+ if (metrics.isEmpty()) {
+ generator.writeEndObject();
+ return;
+ }
+ generator.writeArrayFieldStart("metrics");
+ for (int i = 0; i < metrics.size() - 1; i++) {
+ toJson(metrics.get(i), generator, addStatus);
+ }
+ toJson(metrics.get(metrics.size() - 1), generator, true);
+ generator.writeEndArray();
+ generator.writeEndObject();
+ generator.close();
}
- private static Map<String, YamasJsonModel.YamasJsonNamespace> createYamasJson(Set<ConsumerId> consumers) {
- List<String> namespaces = consumers.stream()
- .filter(consumerId -> consumerId != defaultMetricsConsumerId)
- .map(consumer -> consumer.id)
- .collect(Collectors.toList());
- if (namespaces.isEmpty()) return null;
+ private static void toJson(MetricsPacket metric, JsonGenerator generator, boolean addStatus) throws IOException {
+ generator.writeStartObject();
+ if (addStatus) {
+ generator.writeNumberField("status_code", metric.statusCode);
+ }
+ if (metric.timestamp != 0) {
+ generator.writeNumberField("timestamp", metric.timestamp);
+ }
+ generator.writeStringField("application", metric.service.id);
- YamasJsonModel.YamasJsonNamespace yamasJsonNamespace = new YamasJsonModel.YamasJsonNamespace();
- yamasJsonNamespace.namespaces = namespaces;
- return Map.of(YAMAS_ROUTING, yamasJsonNamespace);
- }
+ if ( ! metric.metrics().isEmpty()) {
+ generator.writeObjectFieldStart("metrics");
+ for (var m : metric.metrics().entrySet()) {
+ generator.writeFieldName(m.getKey().id);
+ JacksonUtil.writeDouble(generator, m.getValue().doubleValue());
+ }
+ generator.writeEndObject();
+ }
+ if ( ! metric.dimensions().isEmpty()) {
+ generator.writeObjectFieldStart("dimensions");
+ for (var m : metric.dimensions().entrySet()) {
+ generator.writeStringField(m.getKey().id, m.getValue());
+ }
+ generator.writeEndObject();
+ }
+ Set<ConsumerId> routing = extractSetForRouting(metric.consumers());
+ if (!routing.isEmpty()) {
+ generator.writeObjectFieldStart("routing");
+ generator.writeObjectFieldStart(YAMAS_ROUTING);
+ generator.writeArrayFieldStart("namespaces");
+ for (ConsumerId consumer : routing) {
+ generator.writeString(consumer.id);
+ }
+ generator.writeEndArray();
+ generator.writeEndObject();
+ generator.writeEndObject();
+ }
+ if (addStatus) {
+ generator.writeStringField("status_msg", metric.statusMessage);
+ }
+ generator.writeEndObject();
+ }
}
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcServer.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcServer.java
index 3a0a9e9cf73..63672e7e600 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcServer.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcServer.java
@@ -4,6 +4,7 @@ package ai.vespa.metricsproxy.rpc;
import ai.vespa.metricsproxy.core.MetricsManager;
import ai.vespa.metricsproxy.metric.model.ConsumerId;
import ai.vespa.metricsproxy.metric.model.MetricsPacket;
+import ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil;
import ai.vespa.metricsproxy.service.VespaService;
import ai.vespa.metricsproxy.service.VespaServices;
import com.yahoo.jrt.ErrorCode;
@@ -17,11 +18,10 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import static ai.vespa.metricsproxy.metric.model.ConsumerId.toConsumerId;
+import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.toJson;
import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.toMetricsPackets;
-import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.toYamasArray;
import static com.yahoo.collections.CollectionUtil.mkString;
import static java.util.logging.Level.FINE;
-import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
/**
@@ -125,9 +125,9 @@ public class RpcServer {
log.log(FINE, () -> "Getting metrics for services: " + mkString(services, "[", ", ", "]"));
if (services.isEmpty()) setNoServiceError(req, service);
else withExceptionHandling(req, () -> {
- List<MetricsPacket> packets = metricsManager.getMetrics(services, startTime);
+ List<MetricsPacket> packets = YamasJsonUtil.appendOptionalStatusPacket(metricsManager.getMetrics(services, startTime));
log.log(FINE,() -> "Returning metrics packets:\n" + mkString(packets, "\n"));
- req.returnValues().add(new StringValue(toYamasArray(packets).serialize()));
+ req.returnValues().add(new StringValue(toJson(packets, false)));
});
req.returnRequest();
}
@@ -138,8 +138,8 @@ public class RpcServer {
List<VespaService> services = vespaServices.getMonitoringServices(service);
if (services.isEmpty()) setNoServiceError(req, service);
else withExceptionHandling(req, () -> {
- List<MetricsPacket> packets = metricsManager.getHealthMetrics(services);
- req.returnValues().add(new StringValue(toYamasArray(packets, true).serialize()));
+ List<MetricsPacket> packets = YamasJsonUtil.appendOptionalStatusPacket(metricsManager.getHealthMetrics(services));
+ req.returnValues().add(new StringValue(toJson(packets, true)));
});
req.returnRequest();
}
diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java
index 540445fba5b..a5bc7a0877a 100644
--- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java
+++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java
@@ -1,15 +1,17 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package ai.vespa.metricsproxy.metric.model.json;
+import ai.vespa.metricsproxy.http.yamas.YamasResponse;
import ai.vespa.metricsproxy.metric.model.MetricsPacket;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.Collections;
+import java.util.List;
import static ai.vespa.metricsproxy.metric.model.ConsumerId.toConsumerId;
import static ai.vespa.metricsproxy.metric.model.MetricId.toMetricId;
@@ -32,10 +34,11 @@ public class YamasJsonModelTest {
public void array_definition_creates_correct_json() throws IOException {
YamasJsonModel jsonModel = getYamasJsonModel("yamas-array.json");
- YamasArrayJsonModel yamasData = new YamasArrayJsonModel();
- yamasData.add(jsonModel);
-
- assertEquals(EXPECTED_JSON, yamasData.serialize());
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ YamasResponse response = new YamasResponse(200, List.of(YamasJsonUtil.toMetricsPacketBuilder(jsonModel).build()));
+ response.render(outputStream);
+ assertEquals(EXPECTED_JSON, outputStream.toString());
+ }
}
@Test
@@ -48,10 +51,11 @@ public class YamasJsonModelTest {
assertEquals(5.555555555E9, jsonModel.metrics.get("memory_rss"), 0.1d); //Not using custom double renderer
// Serialize and verify
- YamasArrayJsonModel yamasArray = new YamasArrayJsonModel();
- yamasArray.add(jsonModel);
- String string = yamasArray.serialize();
- assertEquals(EXPECTED_JSON, string);
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ YamasResponse response = new YamasResponse(200, List.of(YamasJsonUtil.toMetricsPacketBuilder(jsonModel).build()));
+ response.render(outputStream);
+ assertEquals(EXPECTED_JSON, outputStream.toString());
+ }
}
@Test
@@ -65,8 +69,7 @@ public class YamasJsonModelTest {
assertEquals(5.555555555E9, metricsPacket.metrics().get(toMetricId("memory_rss")).doubleValue(), 0.1d); //Not using custom double rendrer
// Serialize and verify
- YamasArrayJsonModel yamasArray = YamasJsonUtil.toYamasArray(Collections.singleton(metricsPacket), true);
- String string = yamasArray.serialize();
+ String string = YamasJsonUtil.toJson(List.of(metricsPacket), true);
assertEquals(EXPECTED_JSON, string);
}
diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java
index 1a0d5c3e149..ebd80b38a42 100644
--- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java
+++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java
@@ -2,8 +2,12 @@
package ai.vespa.metricsproxy.metric.model.json;
import ai.vespa.metricsproxy.metric.model.MetricsPacket;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import org.junit.Test;
+import java.io.IOException;
import java.util.List;
import java.util.Set;
@@ -12,69 +16,75 @@ import static ai.vespa.metricsproxy.http.ValuesFetcher.defaultMetricsConsumerId;
import static ai.vespa.metricsproxy.metric.model.ServiceId.toServiceId;
import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.YAMAS_ROUTING;
import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.toMetricsPackets;
-import static java.util.Collections.singleton;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author gjoranv
*/
public class YamasJsonUtilTest {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+ private static JsonNode metrics(MetricsPacket packet, boolean addStatus) throws IOException {
+ return metrics(List.of(packet), addStatus).get(0);
+ }
+ private static ArrayNode metrics(List<MetricsPacket> packets, boolean addStatus) throws IOException {
+ return (ArrayNode) jsonMapper.readTree(YamasJsonUtil.toJson(packets, addStatus)).get("metrics");
+ }
@Test
- public void json_model_gets_null_status_by_default() {
- MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo"))
- .build();
- YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet)).metrics.get(0);
- assertNull(jsonModel.status_code);
- assertNull(jsonModel.status_msg);
+ public void json_model_gets_null_status_by_default() throws IOException {
+ ArrayNode json = metrics(List.of(new MetricsPacket.Builder(toServiceId("foo")).build(),
+ new MetricsPacket.Builder(toServiceId("bar")).build()), false);
+ assertFalse(json.get(0).has("status_code"));
+ assertFalse(json.get(0).has("status_msg"));
+ assertTrue(json.get(1).has("status_code"));
+ assertTrue(json.get(1).has("status_msg"));
}
@Test
- public void status_is_included_in_json_model_when_explicitly_asked_for() {
- MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo"))
- .build();
- YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet), true).metrics.get(0);
- assertNotNull(jsonModel.status_code);
- assertNotNull(jsonModel.status_msg);
+ public void status_is_included_in_json_model_when_explicitly_asked_for() throws IOException {
+ ArrayNode json = metrics(List.of(new MetricsPacket.Builder(toServiceId("foo")).build(),
+ new MetricsPacket.Builder(toServiceId("bar")).build()), true);
+ assertTrue(json.get(0).has("status_code"));
+ assertTrue(json.get(0).has("status_msg"));
+ assertTrue(json.get(1).has("status_code"));
+ assertTrue(json.get(1).has("status_msg"));
}
@Test
- public void timestamp_0_in_packet_is_translated_to_null_in_json_model() {
- MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo"))
- .timestamp(0L)
- .build();
- YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet)).metrics.get(0);
- assertNull(jsonModel.timestamp);
+ public void timestamp_0_in_packet_is_translated_to_null_in_json_model() throws IOException {
+ MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo")).timestamp(0L).build();
+ JsonNode json = metrics(packet, true);
+ assertFalse(json.has("timestamp"));
}
@Test
- public void empty_consumers_is_translated_to_null_routing_in_json_model() {
- MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo"))
- .build();
- YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet)).metrics.get(0);
- assertNull(jsonModel.routing);
+ public void empty_consumers_is_translated_to_null_routing_in_json_model() throws IOException {
+ MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo")).build();
+ JsonNode json = metrics(packet, true);
+ assertFalse(json.has("routing"));
}
@Test
- public void default_public_consumer_is_filtered_from_yamas_routing() {
+ public void default_public_consumer_is_filtered_from_yamas_routing() throws IOException {
MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo"))
.addConsumers(Set.of(vespaMetricsConsumerId, defaultMetricsConsumerId))
.build();
- YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet)).metrics.get(0);
- List<String> namespaces = jsonModel.routing.get(YAMAS_ROUTING).namespaces;
+ JsonNode json = metrics(packet, false);
+ JsonNode routing = json.get("routing");
+ JsonNode yamas = routing.get(YAMAS_ROUTING);
+ ArrayNode namespaces = (ArrayNode) yamas.get("namespaces");
assertEquals(1, namespaces.size());
- assertEquals(vespaMetricsConsumerId.id, namespaces.get(0));
+ assertEquals(vespaMetricsConsumerId.id, namespaces.get(0).asText());
}
@Test
- public void only_default_public_consumer_yields_null_routing_in_json_model() {
+ public void only_default_public_consumer_yields_null_routing_in_json_model() throws IOException {
MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo"))
.addConsumers(Set.of(defaultMetricsConsumerId))
.build();
- YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet)).metrics.get(0);
- assertNull(jsonModel.routing);
+ JsonNode json = metrics(packet, false);
+ assertFalse(json.has(YAMAS_ROUTING));
}
@Test
diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java
index 214df36d6a1..8a489ac70c7 100644
--- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java
+++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java
@@ -150,7 +150,7 @@ public class RpcMetricsTest {
JsonNode jsonObject = metrics.get(i);
assertFalse(jsonObject.has("status_code"));
assertFalse(jsonObject.has("status_msg"));
- assertThat(jsonObject.get("dimensions").get("foo").textValue(), is("bar"));
+ assertEquals("bar", jsonObject.get("dimensions").get("foo").textValue());
assertThat(jsonObject.get("dimensions").get("bar").textValue(), is("foo"));
assertThat(jsonObject.get("dimensions").get("serviceDim").textValue(), is("serviceDimValue"));
assertThat(jsonObject.get("routing").get("yamas").get("namespaces").size(), is(1));