aboutsummaryrefslogtreecommitdiffstats
path: root/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2021-03-09 08:12:21 +0100
committerHenning Baldersheim <balder@yahoo-inc.com>2021-03-09 08:12:21 +0100
commit97d8918b2805ec3c54be7aff8c888c2a9d5ca9ad (patch)
treee6222a2a0aa844eb4fb76162d9d6cbd3fad831f5 /metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java
parentb04ec57706b4d30711f76ebb8cb7fc8c8469b0a9 (diff)
Move the parser out to prepare for simpler testing.
Diffstat (limited to 'metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java')
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java144
1 files changed, 1 insertions, 143 deletions
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java
index 54976f70e55..314d556b9b4 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java
@@ -1,21 +1,9 @@
// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package ai.vespa.metricsproxy.service;
-import ai.vespa.metricsproxy.metric.Metric;
import ai.vespa.metricsproxy.metric.Metrics;
-import ai.vespa.metricsproxy.metric.model.DimensionId;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import static ai.vespa.metricsproxy.metric.model.DimensionId.toDimensionId;
/**
* Fetch metrics for a given vespa service
@@ -24,8 +12,6 @@ import static ai.vespa.metricsproxy.metric.model.DimensionId.toDimensionId;
*/
public class RemoteMetricsFetcher extends HttpMetricFetcher {
- private static final ObjectMapper jsonMapper = new ObjectMapper();
-
final static String METRICS_PATH = STATE_PATH + "metrics";
RemoteMetricsFetcher(VespaService service, int port) {
@@ -46,142 +32,14 @@ public class RemoteMetricsFetcher extends HttpMetricFetcher {
return createMetrics(data, fetchCount);
}
- /**
- * Connect to remote service over http and fetch metrics
- */
Metrics createMetrics(String data, int fetchCount) {
Metrics remoteMetrics = new Metrics();
try {
- remoteMetrics = parse(data);
+ remoteMetrics = MetricsParser.parse(data);
} catch (Exception e) {
handleException(e, data, fetchCount);
}
return remoteMetrics;
}
-
- private Metrics parseSnapshot(JsonParser parser) throws IOException {
- if (parser.getCurrentToken() != JsonToken.START_OBJECT) {
- throw new IOException("Expected start of 'snapshot' object, got " + parser.currentToken());
- }
- Metrics metrics = new Metrics();
- for (parser.nextToken(); parser.getCurrentToken() != JsonToken.END_OBJECT; parser.nextToken()) {
- String fieldName = parser.getCurrentName();
- JsonToken token = parser.nextToken();
- if (fieldName.equals("to")) {
- long timestamp = parser.getLongValue();
- long now = System.currentTimeMillis() / 1000;
- timestamp = Metric.adjustTime(timestamp, now);
- metrics = new Metrics(timestamp);
- } else {
- if (token == JsonToken.START_OBJECT || token == JsonToken.START_ARRAY) {
- parser.skipChildren();
- }
- }
- }
- return metrics;
- }
-
- private void parseValues(JsonParser parser, Metrics metrics) throws IOException {
- if (parser.getCurrentToken() != JsonToken.START_ARRAY) {
- throw new IOException("Expected start of 'metrics:values' array, got " + parser.currentToken());
- }
-
- Map<String, Map<DimensionId, String>> uniqueDimensions = new HashMap<>();
- while (parser.nextToken() == JsonToken.START_OBJECT) {
- // read everything from this START_OBJECT to the matching END_OBJECT
- // and return it as a tree model ObjectNode
- JsonNode value = jsonMapper.readTree(parser);
- handleValue(value, metrics.getTimeStamp(), metrics, uniqueDimensions);
-
- // do whatever you need to do with this object
- }
- }
-
- private Metrics parseMetrics(JsonParser parser) throws IOException {
- if (parser.getCurrentToken() != JsonToken.START_OBJECT) {
- throw new IOException("Expected start of 'metrics' object, got " + parser.currentToken());
- }
- Metrics metrics = new Metrics();
- for (parser.nextToken(); parser.getCurrentToken() != JsonToken.END_OBJECT; parser.nextToken()) {
- String fieldName = parser.getCurrentName();
- JsonToken token = parser.nextToken();
- if (fieldName.equals("snapshot")) {
- metrics = parseSnapshot(parser);
- } else if (fieldName.equals("values")) {
- parseValues(parser, metrics);
- } else {
- if (token == JsonToken.START_OBJECT || token == JsonToken.START_ARRAY) {
- parser.skipChildren();
- }
- }
- }
- return metrics;
- }
- private Metrics parse(String data) throws IOException {
- JsonParser parser = jsonMapper.createParser(data);
-
- if (parser.nextToken() != JsonToken.START_OBJECT) {
- throw new IOException("Expected start of object, got " + parser.currentToken());
- }
-
- Metrics metrics = new Metrics();
- for (parser.nextToken(); parser.getCurrentToken() != JsonToken.END_OBJECT; parser.nextToken()) {
- String fieldName = parser.getCurrentName();
- JsonToken token = parser.nextToken();
- if (fieldName.equals("metrics")) {
- metrics = parseMetrics(parser);
- } else {
- if (token == JsonToken.START_OBJECT || token == JsonToken.START_ARRAY) {
- parser.skipChildren();
- }
- }
- }
- return metrics;
- }
-
- private void handleValue(JsonNode metric, long timestamp, Metrics metrics, Map<String, Map<DimensionId, String>> uniqueDimensions) {
- String name = metric.get("name").textValue();
- String description = "";
-
- if (metric.has("description")) {
- description = metric.get("description").textValue();
- }
-
- Map<DimensionId, String> dim = Collections.emptyMap();
- if (metric.has("dimensions")) {
- JsonNode dimensions = metric.get("dimensions");
- StringBuilder sb = new StringBuilder();
- for (Iterator<?> it = dimensions.fieldNames(); it.hasNext(); ) {
- String k = (String) it.next();
- String v = dimensions.get(k).asText();
- sb.append(toDimensionId(k)).append(v);
- }
- if ( ! uniqueDimensions.containsKey(sb.toString())) {
- dim = new HashMap<>();
- for (Iterator<?> it = dimensions.fieldNames(); it.hasNext(); ) {
- String k = (String) it.next();
- String v = dimensions.get(k).textValue();
- dim.put(toDimensionId(k), v);
- }
- uniqueDimensions.put(sb.toString(), Collections.unmodifiableMap(dim));
- }
- dim = uniqueDimensions.get(sb.toString());
- }
-
- JsonNode aggregates = metric.get("values");
- for (Iterator<?> it = aggregates.fieldNames(); it.hasNext(); ) {
- String aggregator = (String) it.next();
- JsonNode aggregatorValue = aggregates.get(aggregator);
- if (aggregatorValue == null) {
- throw new IllegalArgumentException("Value for aggregator '" + aggregator + "' is missing");
- }
- Number value = aggregatorValue.numberValue();
- if (value == null) {
- throw new IllegalArgumentException("Value for aggregator '" + aggregator + "' is not a number");
- }
- StringBuilder metricName = (new StringBuilder()).append(name).append(".").append(aggregator);
- metrics.add(new Metric(metricName.toString(), value, timestamp, dim, description));
- }
- }
}