summaryrefslogtreecommitdiffstats
path: root/metrics
diff options
context:
space:
mode:
authorOla Aunronning <olaa@yahooinc.com>2023-09-28 15:57:02 +0200
committerOla Aunronning <olaa@yahooinc.com>2023-09-28 15:57:02 +0200
commit19d86646f1b7c59c607364ea09e736e97d3bd994 (patch)
treea0e5ff635baf86a8f91c5d88e5f7c779649fcaff /metrics
parent791ab8dc2d9c9febb1ef93977fe990d66434c341 (diff)
Metric doc generator
Diffstat (limited to 'metrics')
-rw-r--r--metrics/src/main/java/ai/vespa/metrics/docs/DocumentationGenerator.java65
-rw-r--r--metrics/src/main/java/ai/vespa/metrics/docs/MetricDocumentation.java57
-rw-r--r--metrics/src/main/java/ai/vespa/metrics/docs/MetricSetDocumentation.java105
-rw-r--r--metrics/src/main/java/ai/vespa/metrics/docs/UnitDocumentation.java56
4 files changed, 283 insertions, 0 deletions
diff --git a/metrics/src/main/java/ai/vespa/metrics/docs/DocumentationGenerator.java b/metrics/src/main/java/ai/vespa/metrics/docs/DocumentationGenerator.java
new file mode 100644
index 00000000000..9d63d4af159
--- /dev/null
+++ b/metrics/src/main/java/ai/vespa/metrics/docs/DocumentationGenerator.java
@@ -0,0 +1,65 @@
+package ai.vespa.metrics.docs;
+
+import ai.vespa.metrics.ClusterControllerMetrics;
+import ai.vespa.metrics.ConfigServerMetrics;
+import ai.vespa.metrics.ContainerMetrics;
+import ai.vespa.metrics.DistributorMetrics;
+import ai.vespa.metrics.LogdMetrics;
+import ai.vespa.metrics.NodeAdminMetrics;
+import ai.vespa.metrics.SearchNodeMetrics;
+import ai.vespa.metrics.SentinelMetrics;
+import ai.vespa.metrics.SlobrokMetrics;
+import ai.vespa.metrics.StorageMetrics;
+import ai.vespa.metrics.Unit;
+import ai.vespa.metrics.VespaMetrics;
+import ai.vespa.metrics.set.DefaultMetrics;
+import ai.vespa.metrics.set.MetricSet;
+import ai.vespa.metrics.set.VespaMetricSet;
+
+import java.util.Map;
+import static ai.vespa.metrics.docs.MetricDocumentation.writeMetricDocumentation;
+import static ai.vespa.metrics.docs.MetricSetDocumentation.writeMetricSetDocumentation;
+
+/**
+ * @author olaa
+ *
+ * Helper class to generate metric reference documentation for docs.vespa.ai
+ */
+public class DocumentationGenerator {
+
+ public static void main(String[] args) {
+
+ if (args.length != 1) {
+ throw new IllegalArgumentException("Expected exactly one argument: directory to write to");
+ }
+ var path = args[0];
+
+ var metrics = getMetrics();
+ metrics.forEach((metricType, metricArray) -> writeMetricDocumentation(path, metricArray, metricType));
+
+ var metricSets = getMetricSets();
+ metricSets.forEach((name, metricSet) -> writeMetricSetDocumentation(path, name, metricSet, metrics));
+
+ UnitDocumentation.writeUnitDocumentation(path, Unit.values());
+ }
+
+ private static Map<String, VespaMetrics[]> getMetrics() {
+ return Map.of(
+ "Container", ContainerMetrics.values(),
+ "SearchNode", SearchNodeMetrics.values(),
+ "Storage", StorageMetrics.values(),
+ "Distributor", DistributorMetrics.values(),
+ "ConfigServer", ConfigServerMetrics.values(),
+ "Logd", LogdMetrics.values(),
+ "NodeAdmin", NodeAdminMetrics.values(),
+ "Slobrok", SlobrokMetrics.values(),
+ "Sentinel", SentinelMetrics.values(),
+ "ClusterController", ClusterControllerMetrics.values()
+ );
+ }
+
+ private static Map<String, MetricSet> getMetricSets() {
+ return Map.of("Vespa", VespaMetricSet.vespaMetricSet,
+ "Default", DefaultMetrics.defaultMetricSet);
+ }
+}
diff --git a/metrics/src/main/java/ai/vespa/metrics/docs/MetricDocumentation.java b/metrics/src/main/java/ai/vespa/metrics/docs/MetricDocumentation.java
new file mode 100644
index 00000000000..fc46c785f0e
--- /dev/null
+++ b/metrics/src/main/java/ai/vespa/metrics/docs/MetricDocumentation.java
@@ -0,0 +1,57 @@
+package ai.vespa.metrics.docs;
+
+import ai.vespa.metrics.VespaMetrics;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @author olaa
+ */
+public class MetricDocumentation {
+
+ protected static void writeMetricDocumentation(String path, VespaMetrics[] metrics, String metricType) {
+ var referenceBuilder = new StringBuilder();
+ referenceBuilder.append(String.format("""
+ ---
+ # Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+ title: "%s Metrics"
+ ---
+
+ <table class="table">
+ <thead>
+ <tr><th>Name</th><th>Description</th><th>Unit</th></tr>
+ </thead>
+ <tbody>
+ %s </tbody>
+ </table>
+ """, metricType, htmlRows(metrics)));
+
+ try (FileWriter fileWriter = new FileWriter(path + "/" + metricType.toLowerCase() + "-metrics-reference.html")) {
+ fileWriter.write(referenceBuilder.toString());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ private static String htmlRows(VespaMetrics[] metrics) {
+ return Stream.of(metrics)
+ .map(metric ->
+ String.format(
+ """
+ <tr>
+ <td><p id="%s">%s</p></td>
+ <td>%s</td>
+ <td>%s</td>
+ </tr>
+ """,
+ metric.baseName().replaceAll("\\.", "_"),
+ metric.baseName(),
+ metric.description(),
+ metric.unit().toString().toLowerCase())
+ ).collect(Collectors.joining());
+ }
+}
diff --git a/metrics/src/main/java/ai/vespa/metrics/docs/MetricSetDocumentation.java b/metrics/src/main/java/ai/vespa/metrics/docs/MetricSetDocumentation.java
new file mode 100644
index 00000000000..bafefbfedd6
--- /dev/null
+++ b/metrics/src/main/java/ai/vespa/metrics/docs/MetricSetDocumentation.java
@@ -0,0 +1,105 @@
+package ai.vespa.metrics.docs;
+
+import ai.vespa.metrics.Suffix;
+import ai.vespa.metrics.VespaMetrics;
+import ai.vespa.metrics.set.MetricSet;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author olaa
+ */
+public class MetricSetDocumentation {
+
+ protected static void writeMetricSetDocumentation(String path, String name, MetricSet metricSet, Map<String, VespaMetrics[]> metricsByType) {
+
+ var groupedBySuffix = metricSet.getMetrics()
+ .keySet()
+ .stream()
+ .map(MetricSetDocumentation::withSuffix)
+ .collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toCollection(LinkedHashSet::new))));
+
+ var metricTypeByName = metricsByType.entrySet()
+ .stream()
+ .collect(Collectors.toMap(Map.Entry::getKey,
+ entry -> Arrays.stream(entry.getValue())
+ .filter(val -> groupedBySuffix.containsKey(val.baseName()))
+ .collect(Collectors.toMap(
+ val -> val,
+ val -> groupedBySuffix.get(val.baseName()),
+ (a, b) -> a,
+ LinkedHashMap::new
+ )),
+ (a, b) -> a,
+ LinkedHashMap::new));
+
+ var referenceBuilder = new StringBuilder();
+ referenceBuilder.append(String.format("""
+ ---
+ # Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+ title: "%s Metric Set"
+ ---""", name));
+ metricsByType.keySet()
+ .stream()
+ .sorted()
+ .filter(m -> !metricTypeByName.get(m).isEmpty())
+ .forEach(type ->
+ referenceBuilder.append(String.format("""
+
+ <h2 id="%s-metrics">%s Metrics</h2>
+ <table class="table">
+ <thead>
+ <tr><th>Name</th><th>Description</th><th>Unit</th><th>Suffixes</th></tr>
+ </thead>
+ <tbody>
+ %s </tbody>
+ </table>
+ """, type.toLowerCase(), type, htmlRows(metricTypeByName.get(type))))
+ );
+ try (FileWriter fileWriter = new FileWriter(path + "/" + metricSet.getId().toLowerCase() + "-set-metrics-reference.html")) {
+ fileWriter.write(referenceBuilder.toString());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ private static String htmlRows(Map<VespaMetrics, LinkedHashSet<String>> metrics) {
+ return metrics.entrySet()
+ .stream()
+ .map(entry ->
+ String.format(
+ """
+ <tr>
+ <td><p id="%s">%s</p></td>
+ <td>%s</td>
+ <td>%s</td>
+ <td>%s</td>
+ </tr>
+ """,
+ entry.getKey().baseName().replaceAll("\\.", "_"),
+ entry.getKey().baseName(),
+ entry.getKey().description(),
+ entry.getKey().unit().toString().toLowerCase(),
+ String.join(", ", entry.getValue()))
+
+ ).collect(Collectors.joining());
+ }
+
+ private static Map.Entry<String, String> withSuffix(String metricName) {
+ try {
+ var suffixIndex = metricName.lastIndexOf(".");
+ var suffix = Suffix.valueOf(metricName.substring(suffixIndex + 1));
+ return Map.entry(metricName.substring(0, suffixIndex), suffix.toString());
+ } catch (Exception e) {
+ return Map.entry(metricName, "N/A");
+ }
+ }
+
+}
diff --git a/metrics/src/main/java/ai/vespa/metrics/docs/UnitDocumentation.java b/metrics/src/main/java/ai/vespa/metrics/docs/UnitDocumentation.java
new file mode 100644
index 00000000000..03f99a076b1
--- /dev/null
+++ b/metrics/src/main/java/ai/vespa/metrics/docs/UnitDocumentation.java
@@ -0,0 +1,56 @@
+package ai.vespa.metrics.docs;
+
+
+import ai.vespa.metrics.Unit;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @author olaa
+ */
+public class UnitDocumentation {
+
+ protected static void writeUnitDocumentation(String path, Unit[] units) {
+ var referenceBuilder = new StringBuilder();
+ referenceBuilder.append(String.format("""
+ ---
+ # Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+ title: "Metric Units Reference"
+ ---
+
+
+ <table class="table">
+ <thead>
+ <tr><th>Unit</th><th>Description</th></tr>
+ </thead>
+ <tbody>
+ %s </tbody>
+ </table>
+ """, htmlRows(units)));
+
+ try (FileWriter fileWriter = new FileWriter(path + "/unit-metrics-reference.html")) {
+ fileWriter.write(referenceBuilder.toString());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ private static String htmlRows(Unit[] units) {
+ return Stream.of(units)
+ .map(unit ->
+ String.format(
+ """
+ <tr>
+ <td>%s</td>
+ <td>%s</td>
+ </tr>
+ """,
+ unit.fullName(),
+ unit.getDescription())
+ ).collect(Collectors.joining());
+ }
+}