aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server/src/main/java/com/yahoo
diff options
context:
space:
mode:
authorØyvind Grønnesby <oyving@yahooinc.com>2023-03-08 15:04:28 +0100
committerGitHub <noreply@github.com>2023-03-08 15:04:28 +0100
commit2134efb6eb0f3988571e773f5fe996ec3c3e47ab (patch)
treeeea17153b99b95678d2b5224c77a4bc51412224b /controller-server/src/main/java/com/yahoo
parentb180fdfea329bc7e6e09cbcd1fefe67dc2f22202 (diff)
parent3c325c2ee25bc1d39190dfe7ee5b43eadc6225c0 (diff)
Merge pull request #26173 from vespa-engine/ogronnesby/billing-dimensions
New billing dimensions
Diffstat (limited to 'controller-server/src/main/java/com/yahoo')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceMeterMaintainer.java52
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandler.java9
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/MeteringResponse.java8
4 files changed, 42 insertions, 29 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceMeterMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceMeterMaintainer.java
index d47b82a231f..26edd210075 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceMeterMaintainer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceMeterMaintainer.java
@@ -120,7 +120,7 @@ public class ResourceMeterMaintainer extends ControllerMaintainer {
Map<ZoneId, Double> deploymentCosts = snapshotsByInstance.getOrDefault(instanceName, List.of()).stream()
.collect(Collectors.toUnmodifiableMap(
ResourceSnapshot::getZoneId,
- snapshot -> cost(snapshot.allocation(), systemName),
+ snapshot -> cost(snapshot.resources(), systemName),
Double::sum));
locked = locked.with(instanceName, i -> i.withDeploymentCosts(deploymentCosts));
updateCostMetrics(tenantAndApplication.instance(instanceName), deploymentCosts);
@@ -201,10 +201,11 @@ public class ResourceMeterMaintainer extends ControllerMaintainer {
// Grouping by ApplicationId -> Architecture -> ResourceSnapshot
.collect(Collectors.groupingBy(node ->
node.owner().get(),
- groupSnapshotsByArchitecture(zoneId)))
+ groupSnapshotsByArchitectureAndMajorVersion(zoneId)))
.values()
.stream()
- .flatMap(list -> list.values().stream())
+ .flatMap(byArch -> byArch.values().stream())
+ .flatMap(byMajor -> byMajor.values().stream())
.toList();
}
@@ -234,10 +235,14 @@ public class ResourceMeterMaintainer extends ControllerMaintainer {
}
private static double cost(ResourceAllocation allocation, SystemName systemName) {
+ var resources = new NodeResources(allocation.getCpuCores(), allocation.getMemoryGb(), allocation.getDiskGb(), 0);
+ return cost(resources, systemName);
+ }
+
+ private static double cost(NodeResources resources, SystemName systemName) {
// Divide cost by 3 in non-public zones to show approx. AWS equivalent cost
double costDivisor = systemName.isPublic() ? 1.0 : 3.0;
- double cost = new NodeResources(allocation.getCpuCores(), allocation.getMemoryGb(), allocation.getDiskGb(), 0).cost();
- return Math.round(cost * 100.0 / costDivisor) / 100.0;
+ return Math.round(resources.cost() * 100.0 / costDivisor) / 100.0;
}
private void updateMeteringMetrics(Collection<ResourceSnapshot> resourceSnapshots) {
@@ -245,14 +250,14 @@ public class ResourceMeterMaintainer extends ControllerMaintainer {
// total metered resource usage, for alerting on drastic changes
metric.set(METERING_TOTAL_REPORTED,
resourceSnapshots.stream()
- .mapToDouble(r -> r.getCpuCores() + r.getMemoryGb() + r.getDiskGb()).sum(),
+ .mapToDouble(r -> r.resources().vcpu() + r.resources().memoryGb() + r.resources().diskGb()).sum(),
metric.createContext(Collections.emptyMap()));
resourceSnapshots.forEach(snapshot -> {
var context = getMetricContext(snapshot);
- metric.set("metering.vcpu", snapshot.getCpuCores(), context);
- metric.set("metering.memoryGB", snapshot.getMemoryGb(), context);
- metric.set("metering.diskGB", snapshot.getDiskGb(), context);
+ metric.set("metering.vcpu", snapshot.resources().vcpu(), context);
+ metric.set("metering.memoryGB", snapshot.resources().memoryGb(), context);
+ metric.set("metering.diskGB", snapshot.resources().diskGb(), context);
});
}
@@ -276,23 +281,26 @@ public class ResourceMeterMaintainer extends ControllerMaintainer {
"tenant", snapshot.getApplicationId().tenant().value(),
"applicationId", snapshot.getApplicationId().toFullString(),
"zoneId", snapshot.getZoneId().value(),
- "architecture", snapshot.getArchitecture()
+ "architecture", snapshot.resources().architecture()
));
}
- private Collector<Node, ?, Map<NodeResources.Architecture, ResourceSnapshot>> groupSnapshotsByArchitecture(ZoneId zoneId) {
- return Collectors.collectingAndThen(
- Collectors.groupingBy(node -> node.resources().architecture()),
- convertNodeListToResourceSnapshot(zoneId)
- );
+ private Collector<Node, ?, Map<NodeResources.Architecture, Map<Integer, ResourceSnapshot>>> groupSnapshotsByArchitectureAndMajorVersion(ZoneId zoneId) {
+ return Collectors.groupingBy(
+ (Node node) -> node.resources().architecture(),
+ Collectors.collectingAndThen(
+ Collectors.groupingBy(
+ (Node node) -> node.currentVersion().getMajor(),
+ Collectors.toList()),
+ convertNodeListToResourceSnapshot(zoneId)));
}
- private Function<Map<NodeResources.Architecture, List<Node>>, Map<NodeResources.Architecture, ResourceSnapshot>> convertNodeListToResourceSnapshot(ZoneId zoneId) {
- return nodeMap -> nodeMap.entrySet()
- .stream()
- .collect(Collectors.toMap(
- Map.Entry::getKey,
- entry -> ResourceSnapshot.from(entry.getValue(), clock.instant(), zoneId))
- );
+ private Function<Map<Integer, List<Node>>, Map<Integer, ResourceSnapshot>> convertNodeListToResourceSnapshot(ZoneId zoneId) {
+ return nodesByMajor -> {
+ return nodesByMajor.entrySet().stream()
+ .collect(Collectors.toMap(
+ entry -> entry.getKey(),
+ entry -> ResourceSnapshot.from(entry.getValue(), clock.instant(), zoneId)));
+ };
}
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandler.java
index 6e012ba619d..bc7dd4199c7 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandler.java
@@ -35,8 +35,6 @@ import java.io.IOException;
import java.math.BigDecimal;
import java.security.Principal;
import java.time.LocalDate;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Comparator;
@@ -44,7 +42,6 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executor;
-import java.util.stream.Collectors;
/**
* @author andreer
@@ -421,6 +418,12 @@ public class BillingApiHandler extends ThreadedHttpRequestHandler {
cursor.setString("zone", zoneId.value())
);
+ lineItem.getArchitecture().ifPresent(architecture -> {
+ cursor.setString("architecture", architecture.name());
+ });
+
+ cursor.setLong("majorVersion", lineItem.getMajorVersion());
+
lineItem.getCpuHours().ifPresent(cpuHours ->
cursor.setString("cpuHours", cpuHours.toString())
);
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2.java
index 0ddaa409ef8..67dd172fd83 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2.java
@@ -311,6 +311,8 @@ public class BillingApiHandlerV2 extends RestApiRequestHandler<BillingApiHandler
slime.setString("description", item.description());
slime.setString("amount",item.amount().toString());
toSlime(slime.setObject("plan"), planRegistry.plan(item.plan()).orElseThrow(() -> new RuntimeException("No such plan: '" + item.plan() + "'")));
+ item.getArchitecture().ifPresent(arch -> slime.setString("architecture", arch.name()));
+ slime.setLong("majorVersion", item.getMajorVersion());
item.applicationId().ifPresent(appId -> {
slime.setString("application", appId.application().value());
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/MeteringResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/MeteringResponse.java
index 17461aafd02..7df216d6c9c 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/MeteringResponse.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/MeteringResponse.java
@@ -29,10 +29,10 @@ public class MeteringResponse extends SlimeJsonResponse {
object.setString("applicationId", snapshot.getApplicationId().toShortString());
object.setLong("timestamp", snapshot.getTimestamp().toEpochMilli());
object.setString("zoneId", snapshot.getZoneId().value());
- object.setDouble("cpu", snapshot.getCpuCores());
- object.setDouble("memory", snapshot.getMemoryGb());
- object.setDouble("disk", snapshot.getDiskGb());
- object.setString("architecture", snapshot.getArchitecture().name());
+ object.setDouble("cpu", snapshot.resources().vcpu());
+ object.setDouble("memory", snapshot.resources().memoryGb());
+ object.setDouble("disk", snapshot.resources().diskGb());
+ object.setString("architecture", snapshot.resources().architecture().name());
});
return slime;
}