diff options
author | Martin Polden <mpolden@mpolden.no> | 2022-07-12 15:22:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-12 15:22:11 +0200 |
commit | e6bc7357b016d49f4f876ed3fae497741236368e (patch) | |
tree | e5318ce9d49109f9d6ad33aa335e5cf969cbd4cc | |
parent | e063ef1f7f5a2e7a9389e56f3fc53c5cb1793f55 (diff) | |
parent | 7f3afcb4d074b5f038d1fe204bd1cbc24c88b0a1 (diff) |
Merge pull request #23473 from vespa-engine/bratseth/total-cost
Bratseth/total cost
9 files changed, 58 insertions, 12 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java index 68ebc5e86aa..5ddf5aaff28 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java @@ -8,16 +8,23 @@ import java.util.List; */ public class NodeRepoStats { + private final double totalCost; + private final double totalAllocatedCost; private final Load load; private final Load activeLoad; private final List<ApplicationStats> applicationStats; - public NodeRepoStats(Load load, Load activeLoad, List<ApplicationStats> applicationStats) { + public NodeRepoStats(double totalCost, double totalAllocatedCost, + Load load, Load activeLoad, List<ApplicationStats> applicationStats) { + this.totalCost = totalCost; + this.totalAllocatedCost = totalAllocatedCost; this.load = load; this.activeLoad = activeLoad; this.applicationStats = List.copyOf(applicationStats); } + public double totalCost() { return totalCost; } + public double totalAllocatedCost() { return totalAllocatedCost; } public Load load() { return load; } public Load activeLoad() { return activeLoad; } public List<ApplicationStats> applicationStats() { return applicationStats; } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java index 36677143f7a..75ac919f776 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java @@ -16,6 +16,12 @@ import java.util.stream.Collectors; @JsonInclude(JsonInclude.Include.NON_NULL) public class NodeRepoStatsData { + @JsonProperty("totalCost") + public Double totalCost; + + @JsonProperty("totalAllocatedCost") + public Double totalAllocatedCost; + @JsonProperty("load") public LoadData load; @@ -26,7 +32,8 @@ public class NodeRepoStatsData { public List<ApplicationStatsData> applications; public NodeRepoStats toNodeRepoStats() { - return new NodeRepoStats(load.toLoad(), activeLoad.toLoad(), + return new NodeRepoStats(totalCost, totalAllocatedCost, + load.toLoad(), activeLoad.toLoad(), applications.stream().map(stats -> stats.toApplicationStats()).collect(Collectors.toList())); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/StatsResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/StatsResponse.java index 19f1ac5449f..96a3c9f177d 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/StatsResponse.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/StatsResponse.java @@ -30,6 +30,8 @@ public class StatsResponse extends SlimeJsonResponse { if (stats.applicationStats().isEmpty()) continue; // skip empty zones Cursor zoneObject = zonesArray.addObject(); zoneObject.setString("id", zone.toString()); + zoneObject.setDouble("totalCost", stats.totalCost()); + zoneObject.setDouble("totalAllocatedCost", stats.totalAllocatedCost()); toSlime(stats.load(), zoneObject.setObject("load")); toSlime(stats.activeLoad(), zoneObject.setObject("activeLoad")); Cursor applicationsArray = zoneObject.setArray("applications"); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java index 3f1ca3f9706..93ebdcf3171 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java @@ -107,7 +107,7 @@ public class NodeRepositoryMock implements NodeRepository { .collect(Collectors.toList()) : List.of(); - return new NodeRepoStats(Load.zero(), Load.zero(), applicationStats); + return new NodeRepoStats(0.0, 0.0, Load.zero(), Load.zero(), applicationStats); } @Override diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/stats.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/stats.json index 673767c13a0..44b52e5be2c 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/stats.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/stats.json @@ -2,6 +2,8 @@ "zones": [ { "id": "prod.us-east-3", + "totalCost": 0.0, + "totalAllocatedCost": 0.0, "load": { "cpu": 0.0, "memory": 0.0, @@ -27,6 +29,8 @@ }, { "id": "prod.us-west-1", + "totalCost": 0.0, + "totalAllocatedCost": 0.0, "load": { "cpu": 0.0, "memory": 0.0, diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepoStats.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepoStats.java index 085b89d1253..1460ce70686 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepoStats.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepoStats.java @@ -26,16 +26,23 @@ import java.util.Set; */ public class NodeRepoStats { + private final double totalCost; + private final double totalAllocatedCost; private final Load load; private final Load activeLoad; private final List<ApplicationStats> applicationStats; - private NodeRepoStats(Load load, Load activeLoad, List<ApplicationStats> applicationStats) { + private NodeRepoStats(double totalCost, double totalAllocatedCost, Load load, Load activeLoad, List<ApplicationStats> applicationStats) { + this.totalCost = totalCost; + this.totalAllocatedCost = totalAllocatedCost; this.load = load; this.activeLoad = activeLoad; this.applicationStats = List.copyOf(applicationStats); } + public double totalCost() { return totalCost; } + public double totalAllocatedCost() { return totalAllocatedCost; } + /** * Returns the current average work-extracting utilization in this node repo over all nodes. * Capacity not allocated to active nodes are taken to have 0 utilization as it provides no useful work. @@ -50,11 +57,15 @@ public class NodeRepoStats { public static NodeRepoStats computeOver(NodeRepository nodeRepository) { NodeList allNodes = nodeRepository.nodes().list(); - List<NodeTimeseries> allNodeTimeseries = nodeRepository.metricsDb().getNodeTimeseries(Duration.ofHours(1), Set.of()); + double totalCost = allNodes.hosts().stream().mapToDouble(host -> host.resources().cost()).sum(); + double totalAllocatedCost = allNodes.not().hosts().stream() + .filter(node -> node.allocation().isPresent()) + .mapToDouble(node -> node.resources().cost()).sum(); + List<NodeTimeseries> allNodeTimeseries = nodeRepository.metricsDb().getNodeTimeseries(Duration.ofHours(1), Set.of()); Pair<Load, Load> load = computeLoad(allNodes, allNodeTimeseries); List<ApplicationStats> applicationStats = computeApplicationStats(allNodes, allNodeTimeseries); - return new NodeRepoStats(load.getFirst(), load.getSecond(), applicationStats); + return new NodeRepoStats(totalCost, totalAllocatedCost, load.getFirst(), load.getSecond(), applicationStats); } private static Pair<Load, Load> computeLoad(NodeList allNodes, List<NodeTimeseries> allNodeTimeseries) { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java index c5d8b2518e5..dcfdb32e374 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java @@ -453,6 +453,8 @@ public class NodesV2ApiHandler extends ThreadedHttpRequestHandler { Slime slime = new Slime(); Cursor root = slime.setObject(); + root.setDouble("total-cost", stats.totalCost()); + root.setDouble("total-allocated-cost", stats.totalAllocatedCost()); toSlime(stats.load(), root.setObject("load")); toSlime(stats.activeLoad(), root.setObject("activeLoad")); Cursor applicationsArray = root.setArray("applications"); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/NodeRepoStatsTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/NodeRepoStatsTest.java index 62c96af7629..788c56e08c6 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/NodeRepoStatsTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/NodeRepoStatsTest.java @@ -31,9 +31,13 @@ public class NodeRepoStatsTest { @Test public void testEmpty() { var tester = new NodeRepositoryTester(); - assertLoad(Load.zero(), tester.nodeRepository().computeStats().load()); - assertLoad(Load.zero(), tester.nodeRepository().computeStats().activeLoad()); - assertTrue(tester.nodeRepository().computeStats().applicationStats().isEmpty()); + var stats = tester.nodeRepository().computeStats(); + + assertEquals(0, stats.totalCost(), delta); + assertEquals(0, stats.totalAllocatedCost(), delta); + assertLoad(Load.zero(), stats.load()); + assertLoad(Load.zero(), stats.activeLoad()); + assertTrue(stats.applicationStats().isEmpty()); } @Test @@ -42,9 +46,13 @@ public class NodeRepoStatsTest { tester.addHost("host1", "default"); tester.addHost("host2", "default"); tester.addHost("host3", "small"); - assertLoad(Load.zero(), tester.nodeRepository().computeStats().load()); - assertLoad(Load.zero(), tester.nodeRepository().computeStats().activeLoad()); - assertTrue(tester.nodeRepository().computeStats().applicationStats().isEmpty()); + var stats = tester.nodeRepository().computeStats(); + + assertEquals(0.76, stats.totalCost(), delta); + assertEquals(0, stats.totalAllocatedCost(), delta); + assertLoad(Load.zero(), stats.load()); + assertLoad(Load.zero(), stats.activeLoad()); + assertTrue(stats.applicationStats().isEmpty()); } @Test @@ -97,6 +105,9 @@ public class NodeRepoStatsTest { var stats = tester.nodeRepository().computeStats(); + assertEquals(26, stats.totalCost(), delta); + assertEquals(8.319999999999999, stats.totalAllocatedCost(), delta); + assertLoad(new Load(0.6180,0.5562,0.4944), stats.load()); assertLoad(new Load(0.4682,0.4214,0.3745), stats.activeLoad()); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/stats.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/stats.json index 8a46f8115be..017a45d2bbe 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/stats.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/stats.json @@ -1,4 +1,6 @@ { + "total-cost" : 8.591999999999999, + "total-allocated-cost": 5.356, "load": { "cpu": 0.0, "memory": 0.0, |