diff options
author | Jon Bratseth <bratseth@gmail.com> | 2020-11-16 12:48:43 +0100 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2020-11-16 12:48:43 +0100 |
commit | 70ca76a2fabe46a809d620d3192d57f95f114290 (patch) | |
tree | 7566ad1cc9f2bb9d5dfb0167651f0ba976ccdfea | |
parent | 1375c8aded9eb18aa8496518948730e28a01224b (diff) |
Add in_rotation metric to containers
3 files changed, 94 insertions, 14 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java index acf9340fa7c..1d4babd7c1d 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java @@ -16,11 +16,15 @@ public class AutoscalingMetrics { private static MetricSet create() { return new MetricSet("autoscaling", - metrics("cpu.util", "mem_total.util", "disk.util", "application_generation")); + metrics("cpu.util", + "mem_total.util", + "disk.util", + "application_generation", + "in_rotation")); } - private static Set<Metric> metrics(String ... names) { - return Arrays.stream(names).map(Metric::new).collect(Collectors.toSet()); + private static Set<Metric> metrics(String ... metrics) { + return Arrays.stream(metrics).map(Metric::new).collect(Collectors.toSet()); } } diff --git a/container-core/src/main/java/com/yahoo/container/handler/VipStatus.java b/container-core/src/main/java/com/yahoo/container/handler/VipStatus.java index 876d05b7be9..bbedf723bfa 100644 --- a/container-core/src/main/java/com/yahoo/container/handler/VipStatus.java +++ b/container-core/src/main/java/com/yahoo/container/handler/VipStatus.java @@ -5,7 +5,9 @@ import com.google.inject.Inject; import com.yahoo.container.QrSearchersConfig; import com.yahoo.container.core.VipStatusConfig; import com.yahoo.container.jdisc.state.StateMonitor; +import com.yahoo.jdisc.Metric; +import java.util.Map; import java.util.stream.Collectors; /** @@ -19,6 +21,8 @@ import java.util.stream.Collectors; */ public class VipStatus { + private final Metric metric; + private final ClustersStatus clustersStatus; private final StateMonitor healthState; @@ -57,15 +61,25 @@ public class VipStatus { public VipStatus(QrSearchersConfig dispatchers, VipStatusConfig vipStatusConfig, ClustersStatus clustersStatus, - StateMonitor healthState) { + StateMonitor healthState, + Metric metric) { this.clustersStatus = clustersStatus; this.healthState = healthState; + this.metric = metric; initiallyInRotation = vipStatusConfig.initiallyInRotation(); clustersStatus.setClusters(dispatchers.searchcluster().stream().map(c -> c.name()).collect(Collectors.toSet())); updateCurrentlyInRotation(); } @Deprecated // TODO: Remove on Vespa 8 + public VipStatus(QrSearchersConfig dispatchers, + VipStatusConfig vipStatusConfig, + ClustersStatus clustersStatus, + StateMonitor healthState) { + this(dispatchers, vipStatusConfig, clustersStatus, healthState, new NullMetric()); + } + + @Deprecated // TODO: Remove on Vespa 8 public VipStatus(QrSearchersConfig dispatchers, ClustersStatus clustersStatus, StateMonitor healthState) { this(dispatchers, new VipStatusConfig.Builder().build(), clustersStatus, healthState); } @@ -134,6 +148,8 @@ public class VipStatus { healthState.status(StateMonitor.Status.up); else if (healthState.status() == StateMonitor.Status.up) healthState.status(StateMonitor.Status.down); + + metric.set("in_rotation", currentlyInRotation ? 1 : 0, metric.createContext(Map.of())); } } @@ -144,4 +160,22 @@ public class VipStatus { } } + private static class NullMetric implements Metric { + + @Override + public void set(String key, Number val, Context ctx) { } + + @Override + public void add(String key, Number val, Context ctx) { } + + @Override + public Context createContext(Map<String, ?> properties) { + return new NullContext(); + } + + private static class NullContext implements Context { + } + + } + } diff --git a/container-core/src/test/java/com/yahoo/container/handler/VipStatusTestCase.java b/container-core/src/test/java/com/yahoo/container/handler/VipStatusTestCase.java index 3f33efa1993..640222e8351 100644 --- a/container-core/src/test/java/com/yahoo/container/handler/VipStatusTestCase.java +++ b/container-core/src/test/java/com/yahoo/container/handler/VipStatusTestCase.java @@ -4,8 +4,11 @@ package com.yahoo.container.handler; import com.yahoo.container.QrSearchersConfig; import com.yahoo.container.core.VipStatusConfig; import com.yahoo.container.jdisc.state.StateMonitor; +import com.yahoo.jdisc.Metric; import org.junit.Test; +import java.util.Map; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -26,7 +29,7 @@ public class VipStatusTestCase { public void testUpRequireAllDown() { String[] clusters = {"cluster1", "cluster2", "cluster3"}; - VipStatus v = createVipStatus(clusters, StateMonitor.Status.initializing, true, new ClustersStatus()); + VipStatus v = createVipStatus(clusters, StateMonitor.Status.initializing, true, new ClustersStatus(), new MetricMock()); assertFalse(v.isInRotation()); addToRotation(clusters, v); assertTrue(v.isInRotation()); @@ -53,15 +56,28 @@ public class VipStatusTestCase { @Test public void testNoClustersConfiguringInitiallyInRotationFalse() { String[] clusters = {}; - VipStatus v = createVipStatus(clusters, StateMonitor.Status.initializing, false, new ClustersStatus()); + VipStatus v = createVipStatus(clusters, StateMonitor.Status.initializing, false, new ClustersStatus(), new MetricMock()); assertFalse(v.isInRotation()); } @Test public void testNoClustersConfiguringInitiallyInRotationTrue() { String[] clusters = {}; - VipStatus v = createVipStatus(clusters, StateMonitor.Status.initializing, true, new ClustersStatus()); + VipStatus v = createVipStatus(clusters, StateMonitor.Status.initializing, true, new ClustersStatus(), new MetricMock()); + assertTrue(v.isInRotation()); + } + + @Test + public void testInRotationMetricFollowsRotationState() { + MetricMock metric = new MetricMock(); + String[] clusters = {"cluster1", "cluster2", "cluster3"}; + + VipStatus v = createVipStatus(clusters, StateMonitor.Status.initializing, true, new ClustersStatus(), metric); + assertFalse(v.isInRotation()); + assertEquals(0, metric.inRotation); + addToRotation(clusters, v); assertTrue(v.isInRotation()); + assertEquals(1, metric.inRotation); } @Test @@ -85,7 +101,7 @@ public class VipStatusTestCase { String[] clusters = {"cluster1", "cluster2", "cluster3"}; - VipStatus v = createVipStatus(clusters, true, clustersStatus, stateMonitor); + VipStatus v = createVipStatus(clusters, true, clustersStatus, stateMonitor, new MetricMock()); assertFalse(v.isInRotation()); assertEquals(StateMonitor.Status.initializing, stateMonitor.status()); @@ -98,7 +114,7 @@ public class VipStatusTestCase { v.removeFromRotation("cluster1"); if (anotherIsDown) v.removeFromRotation("cluster3"); - v = createVipStatus(newClusters, true, clustersStatus, stateMonitor); + v = createVipStatus(newClusters, true, clustersStatus, stateMonitor, new MetricMock()); assertTrue(v.isInRotation()); assertEquals(StateMonitor.Status.up, stateMonitor.status()); @@ -124,18 +140,21 @@ public class VipStatusTestCase { private static VipStatus createVipStatus(String[] clusters, StateMonitor.Status startState, boolean initiallyInRotation, - ClustersStatus clustersStatus) { - return createVipStatus(clusters, initiallyInRotation, clustersStatus, createStateMonitor(startState)); + ClustersStatus clustersStatus, + Metric metric) { + return createVipStatus(clusters, initiallyInRotation, clustersStatus, createStateMonitor(startState), metric); } private static VipStatus createVipStatus(String[] clusters, boolean initiallyInRotation, ClustersStatus clustersStatus, - StateMonitor stateMonitor) { + StateMonitor stateMonitor, + Metric metric) { return new VipStatus(createSearchersConfig(clusters), new VipStatusConfig.Builder().initiallyInRotation(initiallyInRotation).build(), clustersStatus, - stateMonitor); + stateMonitor, + metric); } private static StateMonitor createStateMonitor(StateMonitor.Status startState) { @@ -155,7 +174,7 @@ public class VipStatusTestCase { } private static void verifyStatus(String[] clusters, StateMonitor.Status status) { - VipStatus v = createVipStatus(clusters, status, true, new ClustersStatus()); + VipStatus v = createVipStatus(clusters, status, true, new ClustersStatus(), new MetricMock()); removeFromRotation(clusters, v); // initial state assertFalse(v.isInRotation()); @@ -167,4 +186,27 @@ public class VipStatusTestCase { assertTrue(v.isInRotation()); } + private static class MetricMock implements Metric { + + int inRotation = 0; + + @Override + public void add(String key, Number val, Context ctx) { + throw new RuntimeException("Metric.add called unexpectedly"); + } + + @Override + public void set(String key, Number val, Context ctx) { + if ( ! key.equals("in_rotation")) + throw new RuntimeException("Metric.set called with unexpected key " + key); + inRotation = val.intValue(); + } + + @Override + public Context createContext(Map<String, ?> properties) { return new EmptyContext(); } + + private static class EmptyContext implements Context {} + + } + }
\ No newline at end of file |