From 8a3f26bfa51753c8b602985fc1965105629e5f37 Mon Sep 17 00:00:00 2001 From: Dante Niewenhuis Date: Thu, 6 Feb 2025 10:49:12 +0100 Subject: updated logging and added logging for batteries (#301) * Updated logging * removed DoubleThresholdBatteryPolicy.java --- .../compute/simulator/service/ComputeService.java | 20 ++ .../org/opendc/compute/simulator/host/SimHost.kt | 37 ++-- .../simulator/provisioner/HostsProvisioningStep.kt | 22 +- .../simulator/telemetry/ComputeMetricReader.kt | 29 ++- .../compute/simulator/telemetry/ComputeMonitor.kt | 14 +- .../telemetry/parquet/ComputeExportConfig.kt | 33 ++- .../telemetry/parquet/DfltBatteryExportColumns.kt | 114 ++++++++++ .../telemetry/parquet/DfltHostExportColumns.kt | 20 +- .../parquet/DfltPowerSourceExportColumns.kt | 25 ++- .../telemetry/parquet/DfltServiceExportColumns.kt | 2 +- .../telemetry/parquet/DfltTaskExportColumns.kt | 16 +- .../telemetry/parquet/ParquetComputeMonitor.kt | 23 +- .../compute/simulator/telemetry/table/HostInfo.kt | 35 ---- .../simulator/telemetry/table/HostTableReader.kt | 144 ------------- .../telemetry/table/HostTableReaderImpl.kt | 223 -------------------- .../telemetry/table/PowerSourceTableReader.kt | 74 ------- .../telemetry/table/PowerSourceTableReaderImpl.kt | 118 ----------- .../simulator/telemetry/table/ServiceData.kt | 55 ----- .../telemetry/table/ServiceTableReader.kt | 92 -------- .../telemetry/table/ServiceTableReaderImpl.kt | 123 ----------- .../compute/simulator/telemetry/table/TaskInfo.kt | 35 ---- .../simulator/telemetry/table/TaskTableReader.kt | 139 ------------- .../telemetry/table/TaskTableReaderImpl.kt | 230 -------------------- .../telemetry/table/battery/BatteryInfo.kt | 30 +++ .../telemetry/table/battery/BatteryTableReader.kt | 73 +++++++ .../table/battery/BatteryTableReaderImpl.kt | 131 ++++++++++++ .../simulator/telemetry/table/host/HostInfo.kt | 35 ++++ .../telemetry/table/host/HostTableReader.kt | 144 +++++++++++++ .../telemetry/table/host/HostTableReaderImpl.kt | 221 ++++++++++++++++++++ .../telemetry/table/powerSource/PowerSourceInfo.kt | 30 +++ .../table/powerSource/PowerSourceTableReader.kt | 76 +++++++ .../powerSource/PowerSourceTableReaderImpl.kt | 124 +++++++++++ .../telemetry/table/service/ServiceData.kt | 55 +++++ .../telemetry/table/service/ServiceTableReader.kt | 92 ++++++++ .../table/service/ServiceTableReaderImpl.kt | 123 +++++++++++ .../simulator/telemetry/table/task/TaskInfo.kt | 35 ++++ .../telemetry/table/task/TaskTableReader.kt | 140 +++++++++++++ .../telemetry/table/task/TaskTableReaderImpl.kt | 231 +++++++++++++++++++++ 38 files changed, 1824 insertions(+), 1339 deletions(-) create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltBatteryExportColumns.kt delete mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostInfo.kt delete mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt delete mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReaderImpl.kt delete mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReader.kt delete mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReaderImpl.kt delete mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceData.kt delete mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceTableReader.kt delete mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceTableReaderImpl.kt delete mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskInfo.kt delete mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskTableReader.kt delete mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskTableReaderImpl.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryInfo.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryTableReader.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryTableReaderImpl.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostInfo.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReader.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReaderImpl.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceInfo.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceTableReader.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceTableReaderImpl.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceData.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceTableReader.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceTableReaderImpl.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskInfo.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt (limited to 'opendc-compute/opendc-compute-simulator') diff --git a/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java index 6fa6af60..aa2c13b9 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java +++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java @@ -56,6 +56,7 @@ import org.opendc.compute.simulator.scheduler.SchedulingResultType; import org.opendc.compute.simulator.telemetry.ComputeMetricReader; import org.opendc.compute.simulator.telemetry.SchedulerStats; import org.opendc.simulator.compute.power.SimPowerSource; +import org.opendc.simulator.compute.power.batteries.SimBattery; import org.opendc.simulator.compute.workload.Workload; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -108,6 +109,11 @@ public final class ComputeService implements AutoCloseable { */ private final Set powerSources = new HashSet<>(); + /** + * The available powerSources + */ + private final Set batteries = new HashSet<>(); + /** * The tasks that should be launched by the service. */ @@ -307,6 +313,15 @@ public final class ComputeService implements AutoCloseable { powerSources.add(simPowerSource); } + public void addBattery(SimBattery simBattery) { + // Check if host is already known + if (batteries.contains(simBattery)) { + return; + } + + batteries.add(simBattery); + } + /** * Remove a {@link SimHost} from the scheduling pool of the compute service. */ @@ -341,6 +356,10 @@ public final class ComputeService implements AutoCloseable { return Collections.unmodifiableSet(this.powerSources); } + public Set getBatteries() { + return Collections.unmodifiableSet(this.batteries); + } + public void setMetricReader(ComputeMetricReader metricReader) { this.metricReader = metricReader; } @@ -445,6 +464,7 @@ public final class ComputeService implements AutoCloseable { final HostView hv = result.getHost(); final SchedulingRequest req = result.getReq(); final ServiceTask task = req.getTask(); + final ServiceFlavor flavor = task.getFlavor(); if (task.getNumFailures() >= maxNumFailures) { diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt index cc4ac2d8..132ad227 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt @@ -40,24 +40,21 @@ import org.opendc.simulator.engine.graph.FlowGraph import java.time.Duration import java.time.Instant import java.time.InstantSource -import java.util.UUID /** - * A [Host] implementation that simulates virtual machines on a physical machine. + * A [SimHost] implementation that simulates virtual machines on a physical machine. * - * @param uid The unique identifier of the host. * @param name The name of the host. - * @param meta The metadata of the host. * @param clock The (virtual) clock used to track time. * @param graph The Flow Graph that the Host is part of * @param machineModel The static model of the host - * @param powerModel The static powerModel of the CPU TODO: can this be combined with machinemodel? + * @param cpuPowerModel The power model of the host + * @param powerDistributor The power distributor to which the host is connected * @constructor Create empty Sim host */ public class SimHost( - private val uid: UUID, private val name: String, - private val meta: Map, + private val clusterName: String, private val clock: InstantSource, private val graph: FlowGraph, private val machineModel: MachineModel, @@ -170,20 +167,16 @@ public class SimHost( hostState = state } - public fun getUid(): UUID { - return uid - } - public fun getName(): String { return name } - public fun getModel(): HostModel { - return model + public fun getClusterName(): String { + return clusterName } - public fun getMeta(): Map { - return meta + public fun getModel(): HostModel { + return model } public fun getState(): HostState { @@ -236,12 +229,12 @@ public class SimHost( } public fun start(task: ServiceTask) { - val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.uid} at host $uid" } + val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.name} at host $name" } guest.start() } public fun stop(task: ServiceTask) { - val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.uid} at host $uid" } + val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.name} at host $name" } guest.stop() } @@ -308,7 +301,7 @@ public class SimHost( } public fun getSystemStats(task: ServiceTask): GuestSystemStats { - val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.uid} at host $uid" } + val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.name} at host $name" } return guest.getSystemStats() } @@ -330,17 +323,17 @@ public class SimHost( } public fun getCpuStats(task: ServiceTask): GuestCpuStats { - val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.uid} at host $uid" } + val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.name} at host $name" } return guest.getCpuStats() } - override fun hashCode(): Int = uid.hashCode() + override fun hashCode(): Int = name.hashCode() override fun equals(other: Any?): Boolean { - return other is SimHost && uid == other.uid + return other is SimHost && name == other.name } - override fun toString(): String = "SimHost[uid=$uid,name=$name,model=$model]" + override fun toString(): String = "SimHost[uid=$name,name=$name,model=$model]" /** * Convert flavor to machine model. diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt index 572335e1..fcfa1b7b 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt @@ -39,8 +39,8 @@ import org.opendc.simulator.engine.graph.FlowDistributor * A [ProvisioningStep] that provisions a list of hosts for a [ComputeService]. * * @param serviceDomain The domain name under which the compute service is registered. - * @param specs A list of [HostSpec] objects describing the simulated hosts to provision. - * @param optimize A flag to indicate that the CPU resources of the host should be merged into a single CPU resource. + * @param clusterSpecs A list of [HostSpec] objects describing the simulated hosts to provision. + * @param startTime The absolute start time of the simulation. Used to determine the carbon trace offset. */ public class HostsProvisioningStep internal constructor( private val serviceDomain: String, @@ -62,7 +62,7 @@ public class HostsProvisioningStep internal constructor( // Create the Power Source to which hosts are connected // Create Power Source - val simPowerSource = SimPowerSource(graph, cluster.powerSource.totalPower.toDouble()) + val simPowerSource = SimPowerSource(graph, cluster.powerSource.totalPower.toDouble(), cluster.powerSource.name, cluster.name) simPowerSources.add(simPowerSource) service.addPowerSource(simPowerSource) @@ -84,7 +84,14 @@ public class HostsProvisioningStep internal constructor( // Create Battery val battery = - SimBattery(graph, cluster.battery!!.capacity, cluster.battery!!.chargingSpeed, cluster.battery!!.initialCharge) + SimBattery( + graph, + cluster.battery!!.capacity, + cluster.battery!!.chargingSpeed, + cluster.battery!!.initialCharge, + cluster.battery!!.name, + cluster.name, + ) graph.addEdge(battery, batteryDistributor) // Create Aggregator @@ -102,6 +109,8 @@ public class HostsProvisioningStep internal constructor( carbonModel?.addReceiver(batteryPolicy) graph.addEdge(hostDistributor, batteryAggregator) + + service.addBattery(battery) } else { graph.addEdge(hostDistributor, simPowerSource) } @@ -110,9 +119,8 @@ public class HostsProvisioningStep internal constructor( for (hostSpec in cluster.hostSpecs) { val simHost = SimHost( - hostSpec.uid, hostSpec.name, - hostSpec.meta, + cluster.name, ctx.dispatcher.timeSource, graph, hostSpec.model, @@ -120,7 +128,7 @@ public class HostsProvisioningStep internal constructor( hostDistributor, ) - require(simHosts.add(simHost)) { "Host with uid ${hostSpec.uid} already exists" } + require(simHosts.add(simHost)) { "Host with name ${hostSpec.name} already exists" } service.addHost(simHost) } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt index d5720649..10bc889b 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt @@ -32,11 +32,13 @@ import org.opendc.common.asCoroutineDispatcher import org.opendc.compute.simulator.host.SimHost import org.opendc.compute.simulator.service.ComputeService import org.opendc.compute.simulator.service.ServiceTask -import org.opendc.compute.simulator.telemetry.table.HostTableReaderImpl -import org.opendc.compute.simulator.telemetry.table.PowerSourceTableReaderImpl -import org.opendc.compute.simulator.telemetry.table.ServiceTableReaderImpl -import org.opendc.compute.simulator.telemetry.table.TaskTableReaderImpl +import org.opendc.compute.simulator.telemetry.table.battery.BatteryTableReaderImpl +import org.opendc.compute.simulator.telemetry.table.host.HostTableReaderImpl +import org.opendc.compute.simulator.telemetry.table.powerSource.PowerSourceTableReaderImpl +import org.opendc.compute.simulator.telemetry.table.service.ServiceTableReaderImpl +import org.opendc.compute.simulator.telemetry.table.task.TaskTableReaderImpl import org.opendc.simulator.compute.power.SimPowerSource +import org.opendc.simulator.compute.power.batteries.SimBattery import java.time.Duration /** @@ -85,6 +87,11 @@ public class ComputeMetricReader( */ private val powerSourceTableReaders = mutableMapOf() + /** + * Mapping from [SimPowerSource] instances to [PowerSourceTableReaderImpl] + */ + private val batteryTableReaders = mutableMapOf() + /** * The background job that is responsible for collecting the metrics every cycle. */ @@ -155,6 +162,20 @@ public class ComputeMetricReader( reader.reset() } + for (simBattery in this.service.batteries) { + val reader = + this.batteryTableReaders.computeIfAbsent(simBattery) { + BatteryTableReaderImpl( + it, + startTime, + ) + } + + reader.record(now) + this.monitor.record(reader.copy()) + reader.reset() + } + this.serviceTableReader.record(now) monitor.record(this.serviceTableReader.copy()) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMonitor.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMonitor.kt index 5e1fe2c9..0c10e7a2 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMonitor.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMonitor.kt @@ -22,10 +22,11 @@ package org.opendc.compute.simulator.telemetry -import org.opendc.compute.simulator.telemetry.table.HostTableReader -import org.opendc.compute.simulator.telemetry.table.PowerSourceTableReader -import org.opendc.compute.simulator.telemetry.table.ServiceTableReader -import org.opendc.compute.simulator.telemetry.table.TaskTableReader +import org.opendc.compute.simulator.telemetry.table.battery.BatteryTableReader +import org.opendc.compute.simulator.telemetry.table.host.HostTableReader +import org.opendc.compute.simulator.telemetry.table.powerSource.PowerSourceTableReader +import org.opendc.compute.simulator.telemetry.table.service.ServiceTableReader +import org.opendc.compute.simulator.telemetry.table.task.TaskTableReader /** * A monitor that tracks the metrics and events of the OpenDC Compute service. @@ -46,6 +47,11 @@ public interface ComputeMonitor { */ public fun record(reader: PowerSourceTableReader) {} + /** + * Record an entry with the specified [reader]. + */ + public fun record(reader: BatteryTableReader) {} + /** * Record an entry with the specified [reader]. */ diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ComputeExportConfig.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ComputeExportConfig.kt index 691d01c1..7c753ebf 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ComputeExportConfig.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ComputeExportConfig.kt @@ -35,10 +35,11 @@ import kotlinx.serialization.json.JsonDecoder import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.jsonObject import org.opendc.common.logger.logger -import org.opendc.compute.simulator.telemetry.table.HostTableReader -import org.opendc.compute.simulator.telemetry.table.PowerSourceTableReader -import org.opendc.compute.simulator.telemetry.table.ServiceTableReader -import org.opendc.compute.simulator.telemetry.table.TaskTableReader +import org.opendc.compute.simulator.telemetry.table.battery.BatteryTableReader +import org.opendc.compute.simulator.telemetry.table.host.HostTableReader +import org.opendc.compute.simulator.telemetry.table.powerSource.PowerSourceTableReader +import org.opendc.compute.simulator.telemetry.table.service.ServiceTableReader +import org.opendc.compute.simulator.telemetry.table.task.TaskTableReader import org.opendc.trace.util.parquet.exporter.ColListSerializer import org.opendc.trace.util.parquet.exporter.ExportColumn import org.opendc.trace.util.parquet.exporter.Exportable @@ -58,17 +59,20 @@ public data class ComputeExportConfig( public val hostExportColumns: Set>, public val taskExportColumns: Set>, public val powerSourceExportColumns: Set>, + public val batteryExportColumns: Set>, public val serviceExportColumns: Set>, ) { public constructor( hostExportColumns: Collection>, taskExportColumns: Collection>, powerSourceExportColumns: Collection>, + batteryExportColumns: Collection>, serviceExportColumns: Collection>, ) : this( hostExportColumns.toSet() + DfltHostExportColumns.BASE_EXPORT_COLUMNS, taskExportColumns.toSet() + DfltTaskExportColumns.BASE_EXPORT_COLUMNS, powerSourceExportColumns.toSet() + DfltPowerSourceExportColumns.BASE_EXPORT_COLUMNS, + batteryExportColumns.toSet() + DfltBatteryExportColumns.BASE_EXPORT_COLUMNS, serviceExportColumns.toSet() + DfltServiceExportColumns.BASE_EXPORT_COLUMNS, ) @@ -81,6 +85,7 @@ public data class ComputeExportConfig( | Host columns : ${hostExportColumns.map { it.name }.toString().trim('[', ']')} | Task columns : ${taskExportColumns.map { it.name }.toString().trim('[', ']')} | Power Source columns : ${powerSourceExportColumns.map { it.name }.toString().trim('[', ']')} + | Power Source columns : ${batteryExportColumns.map { it.name }.toString().trim('[', ']')} | Service columns : ${serviceExportColumns.map { it.name }.toString().trim('[', ']')} """.trimIndent() @@ -95,12 +100,13 @@ public data class ComputeExportConfig( DfltHostExportColumns DfltTaskExportColumns DfltPowerSourceExportColumns + DfltBatteryExportColumns DfltServiceExportColumns } /** * Config that includes all columns defined in [DfltHostExportColumns], [DfltTaskExportColumns], - * [DfltPowerSourceExportColumns], [DfltServiceExportColumns] among all other loaded + * [DfltPowerSourceExportColumns], [batteryExportColumns], [DfltServiceExportColumns] among all other loaded * columns for [HostTableReader], [TaskTableReader] and [ServiceTableReader]. */ public val ALL_COLUMNS: ComputeExportConfig by lazy { @@ -109,6 +115,7 @@ public data class ComputeExportConfig( hostExportColumns = ExportColumn.getAllLoadedColumns(), taskExportColumns = ExportColumn.getAllLoadedColumns(), powerSourceExportColumns = ExportColumn.getAllLoadedColumns(), + batteryExportColumns = ExportColumn.getAllLoadedColumns(), serviceExportColumns = ExportColumn.getAllLoadedColumns(), ) } @@ -131,7 +138,11 @@ public data class ComputeExportConfig( ) element( "powerSourceExportColumns", - ListSerializer(columnSerializer()).descriptor, + ListSerializer(columnSerializer()).descriptor, + ) + element( + "batteryExportColumns", + ListSerializer(columnSerializer()).descriptor, ) element( "serviceExportColumns", @@ -153,12 +164,14 @@ public data class ComputeExportConfig( val hostFields: List> = elem["hostExportColumns"].toFieldList() val taskFields: List> = elem["taskExportColumns"].toFieldList() val powerSourceFields: List> = elem["powerSourceExportColumns"].toFieldList() + val batteryFields: List> = elem["batteryExportColumns"].toFieldList() val serviceFields: List> = elem["serviceExportColumns"].toFieldList() return ComputeExportConfig( hostExportColumns = hostFields, taskExportColumns = taskFields, powerSourceExportColumns = powerSourceFields, + batteryExportColumns = batteryFields, serviceExportColumns = serviceFields, ) } @@ -189,6 +202,12 @@ public data class ComputeExportConfig( encodeSerializableElement( descriptor, 3, + ColListSerializer(columnSerializer()), + value.batteryExportColumns.toList(), + ) + encodeSerializableElement( + descriptor, + 4, ColListSerializer(columnSerializer()), value.serviceExportColumns.toList(), ) @@ -204,7 +223,7 @@ private inline fun JsonElement?.toFieldList(): List()), it) }?.ifEmpty { - ComputeExportConfig.Companion.LOG.warn( + ComputeExportConfig.LOG.warn( "deserialized list of export columns for exportable ${T::class.simpleName} " + "produced empty list, falling back to all loaded columns", ) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltBatteryExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltBatteryExportColumns.kt new file mode 100644 index 00000000..274eceab --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltBatteryExportColumns.kt @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2024 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.parquet + +import org.apache.parquet.io.api.Binary +import org.apache.parquet.schema.LogicalTypeAnnotation +import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.BINARY +import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.FLOAT +import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT64 +import org.apache.parquet.schema.Types +import org.opendc.compute.simulator.telemetry.table.battery.BatteryTableReader +import org.opendc.trace.util.parquet.exporter.ExportColumn + +/** + * This object wraps the [ExportColumn]s to solves ambiguity for field + * names that are included in more than 1 exportable. + * + * Additionally, it allows to load all the fields at once by just its symbol, + * so that these columns can be deserialized. Additional fields can be added + * from anywhere, and they are deserializable as long as they are loaded by the jvm. + * + * ```kotlin + * ... + * // Loads the column + * DfltHostExportColumns + * ... + * ``` + */ +public object DfltBatteryExportColumns { + public val TIMESTAMP: ExportColumn = + ExportColumn( + field = Types.required(INT64).named("timestamp"), + ) { it.timestamp.toEpochMilli() } + + public val TIMESTAMP_ABS: ExportColumn = + ExportColumn( + field = Types.required(INT64).named("timestamp_absolute"), + ) { it.timestampAbsolute.toEpochMilli() } + + public val NAME: ExportColumn = + ExportColumn( + field = + Types.required(BINARY) + .`as`(LogicalTypeAnnotation.stringType()) + .named("name"), + ) { Binary.fromString(it.batteryInfo.name) } + + public val CLUSTER_NAME: ExportColumn = + ExportColumn( + field = + Types.required(BINARY) + .`as`(LogicalTypeAnnotation.stringType()) + .named("cluster_name"), + ) { Binary.fromString(it.batteryInfo.clusterName) } + + public val POWER_DRAW: ExportColumn = + ExportColumn( + field = Types.required(FLOAT).named("power_draw"), + ) { it.powerDraw } + + public val ENERGY_USAGE: ExportColumn = + ExportColumn( + field = Types.required(FLOAT).named("energy_usage"), + ) { it.energyUsage } + + public val CHARGE: ExportColumn = + ExportColumn( + field = Types.required(FLOAT).named("charge"), + ) { it.charge } + + public val CAPACITY: ExportColumn = + ExportColumn( + field = Types.required(FLOAT).named("capacity"), + ) { it.capacity } + + public val BATTERY_STATE: ExportColumn = + ExportColumn( + field = + Types.optional(BINARY) + .`as`(LogicalTypeAnnotation.stringType()) + .named("battery_state"), + ) { Binary.fromString(it.batteryState.name) } + + /** + * The columns that are always included in the output file. + */ + internal val BASE_EXPORT_COLUMNS = + setOf( + TIMESTAMP_ABS, + TIMESTAMP, + NAME, + CLUSTER_NAME, + ) +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt index 805b224d..13304b47 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt @@ -29,7 +29,7 @@ import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.FLOAT import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT32 import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT64 import org.apache.parquet.schema.Types -import org.opendc.compute.simulator.telemetry.table.HostTableReader +import org.opendc.compute.simulator.telemetry.table.host.HostTableReader import org.opendc.trace.util.parquet.exporter.ExportColumn /** @@ -58,31 +58,31 @@ public object DfltHostExportColumns { field = Types.required(INT64).named("timestamp_absolute"), ) { it.timestampAbsolute.toEpochMilli() } - public val HOST_ID: ExportColumn = + public val NAME: ExportColumn = ExportColumn( field = Types.required(BINARY) .`as`(LogicalTypeAnnotation.stringType()) - .named("host_id"), - ) { Binary.fromString(it.host.id) } + .named("name"), + ) { Binary.fromString(it.hostInfo.name) } - public val HOST_NAME: ExportColumn = + public val CLUSTER_NAME: ExportColumn = ExportColumn( field = Types.required(BINARY) .`as`(LogicalTypeAnnotation.stringType()) - .named("host_name"), - ) { Binary.fromString(it.host.name) } + .named("cluster_name"), + ) { Binary.fromString(it.hostInfo.clusterName) } public val CPU_COUNT: ExportColumn = ExportColumn( field = Types.required(INT32).named("core_count"), - ) { it.host.coreCount } + ) { it.hostInfo.coreCount } public val MEM_CAPACITY: ExportColumn = ExportColumn( field = Types.required(INT64).named("mem_capacity"), - ) { it.host.memCapacity } + ) { it.hostInfo.memCapacity } public val GUESTS_TERMINATED: ExportColumn = ExportColumn( @@ -181,5 +181,7 @@ public object DfltHostExportColumns { setOf( TIMESTAMP_ABS, TIMESTAMP, + NAME, + CLUSTER_NAME, ) } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltPowerSourceExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltPowerSourceExportColumns.kt index 95db55fe..192667b9 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltPowerSourceExportColumns.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltPowerSourceExportColumns.kt @@ -22,11 +22,13 @@ package org.opendc.compute.simulator.telemetry.parquet +import org.apache.parquet.io.api.Binary +import org.apache.parquet.schema.LogicalTypeAnnotation +import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.BINARY import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.FLOAT -import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT32 import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT64 import org.apache.parquet.schema.Types -import org.opendc.compute.simulator.telemetry.table.PowerSourceTableReader +import org.opendc.compute.simulator.telemetry.table.powerSource.PowerSourceTableReader import org.opendc.trace.util.parquet.exporter.ExportColumn /** @@ -55,10 +57,21 @@ public object DfltPowerSourceExportColumns { field = Types.required(INT64).named("timestamp_absolute"), ) { it.timestampAbsolute.toEpochMilli() } - public val CPU_COUNT: ExportColumn = + public val NAME: ExportColumn = ExportColumn( - field = Types.required(INT32).named("hosts_connected"), - ) { it.hostsConnected } + field = + Types.required(BINARY) + .`as`(LogicalTypeAnnotation.stringType()) + .named("name"), + ) { Binary.fromString(it.powerSourceInfo.name) } + + public val CLUSTER_NAME: ExportColumn = + ExportColumn( + field = + Types.required(BINARY) + .`as`(LogicalTypeAnnotation.stringType()) + .named("cluster_name"), + ) { Binary.fromString(it.powerSourceInfo.clusterName) } public val POWER_DRAW: ExportColumn = ExportColumn( @@ -87,5 +100,7 @@ public object DfltPowerSourceExportColumns { setOf( TIMESTAMP_ABS, TIMESTAMP, + NAME, + CLUSTER_NAME, ) } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltServiceExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltServiceExportColumns.kt index aa08e8ff..374b2d31 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltServiceExportColumns.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltServiceExportColumns.kt @@ -25,7 +25,7 @@ package org.opendc.compute.simulator.telemetry.parquet import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT32 import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT64 import org.apache.parquet.schema.Types -import org.opendc.compute.simulator.telemetry.table.ServiceTableReader +import org.opendc.compute.simulator.telemetry.table.service.ServiceTableReader import org.opendc.trace.util.parquet.exporter.ExportColumn /** diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt index cf315947..52a84236 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt @@ -29,7 +29,7 @@ import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.FLOAT import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT32 import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT64 import org.apache.parquet.schema.Types -import org.opendc.compute.simulator.telemetry.table.TaskTableReader +import org.opendc.compute.simulator.telemetry.table.task.TaskTableReader import org.opendc.trace.util.parquet.exporter.ExportColumn /** @@ -66,13 +66,13 @@ public object DfltTaskExportColumns { .named("task_id"), ) { Binary.fromString(it.taskInfo.id) } - public val HOST_ID: ExportColumn = - ExportColumn( - field = - Types.optional(BINARY) - .`as`(LogicalTypeAnnotation.stringType()) - .named("host_id"), - ) { it.host?.id?.let { Binary.fromString(it) } } +// public val HOST_ID: ExportColumn = +// ExportColumn( +// field = +// Types.optional(BINARY) +// .`as`(LogicalTypeAnnotation.stringType()) +// .named("host_id"), +// ) { it.host?.id?.let { Binary.fromString(it) } } public val TASK_NAME: ExportColumn = ExportColumn( diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ParquetComputeMonitor.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ParquetComputeMonitor.kt index b3150018..7d2b9363 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ParquetComputeMonitor.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ParquetComputeMonitor.kt @@ -23,10 +23,11 @@ package org.opendc.compute.simulator.telemetry.parquet import org.opendc.compute.simulator.telemetry.ComputeMonitor -import org.opendc.compute.simulator.telemetry.table.HostTableReader -import org.opendc.compute.simulator.telemetry.table.PowerSourceTableReader -import org.opendc.compute.simulator.telemetry.table.ServiceTableReader -import org.opendc.compute.simulator.telemetry.table.TaskTableReader +import org.opendc.compute.simulator.telemetry.table.battery.BatteryTableReader +import org.opendc.compute.simulator.telemetry.table.host.HostTableReader +import org.opendc.compute.simulator.telemetry.table.powerSource.PowerSourceTableReader +import org.opendc.compute.simulator.telemetry.table.service.ServiceTableReader +import org.opendc.compute.simulator.telemetry.table.task.TaskTableReader import org.opendc.trace.util.parquet.exporter.ExportColumn import org.opendc.trace.util.parquet.exporter.Exportable import org.opendc.trace.util.parquet.exporter.Exporter @@ -39,6 +40,7 @@ public class ParquetComputeMonitor( private val hostExporter: Exporter, private val taskExporter: Exporter, private val powerSourceExporter: Exporter, + private val batteryExporter: Exporter, private val serviceExporter: Exporter, ) : ComputeMonitor, AutoCloseable { override fun record(reader: HostTableReader) { @@ -53,6 +55,10 @@ public class ParquetComputeMonitor( powerSourceExporter.write(reader) } + override fun record(reader: BatteryTableReader) { + batteryExporter.write(reader) + } + override fun record(reader: ServiceTableReader) { serviceExporter.write(reader) } @@ -61,6 +67,7 @@ public class ParquetComputeMonitor( hostExporter.close() taskExporter.close() powerSourceExporter.close() + batteryExporter.close() serviceExporter.close() } @@ -85,6 +92,7 @@ public class ParquetComputeMonitor( hostExportColumns = computeExportConfig.hostExportColumns, taskExportColumns = computeExportConfig.taskExportColumns, powerSourceExportColumns = computeExportConfig.powerSourceExportColumns, + batteryExportColumns = computeExportConfig.batteryExportColumns, serviceExportColumns = computeExportConfig.serviceExportColumns, ) @@ -104,6 +112,7 @@ public class ParquetComputeMonitor( hostExportColumns: Collection>? = null, taskExportColumns: Collection>? = null, powerSourceExportColumns: Collection>? = null, + batteryExportColumns: Collection>? = null, serviceExportColumns: Collection>? = null, ): ParquetComputeMonitor { // Loads the fields in case they need to be retrieved if optional params are omitted. @@ -128,6 +137,12 @@ public class ParquetComputeMonitor( columns = powerSourceExportColumns ?: Exportable.getAllLoadedColumns(), bufferSize = bufferSize, ), + batteryExporter = + Exporter( + outputFile = File(base, "$partition/battery.parquet").also { it.parentFile.mkdirs() }, + columns = batteryExportColumns ?: Exportable.getAllLoadedColumns(), + bufferSize = bufferSize, + ), serviceExporter = Exporter( outputFile = File(base, "$partition/service.parquet").also { it.parentFile.mkdirs() }, diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostInfo.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostInfo.kt deleted file mode 100644 index 0220971b..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostInfo.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.simulator.telemetry.table - -/** - * Information about a host exposed to the telemetry service. - */ -public data class HostInfo( - val id: String, - val name: String, - val arch: String, - val coreCount: Int, - val coreSpeed: Double, - val memCapacity: Long, -) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt deleted file mode 100644 index 35565f82..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.simulator.telemetry.table - -import org.opendc.trace.util.parquet.exporter.Exportable -import java.time.Instant - -/** - * An interface that is used to read a row of a host trace entry. - */ -public interface HostTableReader : Exportable { - public fun copy(): HostTableReader - - public fun setValues(table: HostTableReader) - - public fun record(now: Instant) - - public fun reset() - - /** - * The [HostInfo] of the host to which the row belongs to. - */ - public val host: HostInfo - - /** - * The timestamp of the current entry of the reader relative to the start of the workload. - */ - public val timestamp: Instant - - /** - * The timestamp of the current entry of the reader. - */ - public val timestampAbsolute: Instant - - /** - * The number of guests that are in a terminated state. - */ - public val guestsTerminated: Int - - /** - * The number of guests that are in a running state. - */ - public val guestsRunning: Int - - /** - * The number of guests that are in an error state. - */ - public val guestsError: Int - - /** - * The number of guests that are in an unknown state. - */ - public val guestsInvalid: Int - - /** - * The capacity of the CPUs in the host (in MHz). - */ - public val cpuLimit: Double - - /** - * The usage of all CPUs in the host (in MHz). - */ - public val cpuUsage: Double - - /** - * The demand of all vCPUs of the guests (in MHz) - */ - public val cpuDemand: Double - - /** - * The CPU utilization of the host. - */ - public val cpuUtilization: Double - - /** - * The duration (in ms) that a CPU was active in the host. - */ - public val cpuActiveTime: Long - - /** - * The duration (in ms) that a CPU was idle in the host. - */ - public val cpuIdleTime: Long - - /** - * The duration (in ms) that a vCPU wanted to run, but no capacity was available. - */ - public val cpuStealTime: Long - - /** - * The duration (in ms) of CPU time that was lost due to interference. - */ - public val cpuLostTime: Long - - /** - * The current power draw of the host in W. - */ - public val powerDraw: Double - - /** - * The total energy consumption of the host since last sample in J. - */ - public val energyUsage: Double - - /** - * The uptime of the host since last time in ms. - */ - public val uptime: Long - - /** - * The downtime of the host since last time in ms. - */ - public val downtime: Long - - /** - * The [Instant] at which the host booted relative to the start of the workload. - */ - public val bootTime: Instant? - - /** - * The [Instant] at which the host booted. - */ - public val bootTimeAbsolute: Instant? -} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReaderImpl.kt deleted file mode 100644 index 90f091f2..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReaderImpl.kt +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2024 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.simulator.telemetry.table - -import org.opendc.compute.simulator.host.SimHost -import java.time.Duration -import java.time.Instant - -/** - * An aggregator for host metrics before they are reported. - */ -public class HostTableReaderImpl( - host: SimHost, - private val startTime: Duration = Duration.ofMillis(0), -) : HostTableReader { - override fun copy(): HostTableReader { - val newHostTable = - HostTableReaderImpl(_host) - newHostTable.setValues(this) - - return newHostTable - } - - override fun setValues(table: HostTableReader) { - _timestamp = table.timestamp - _timestampAbsolute = table.timestampAbsolute - - _guestsTerminated = table.guestsTerminated - _guestsRunning = table.guestsRunning - _guestsError = table.guestsError - _guestsInvalid = table.guestsInvalid - _cpuLimit = table.cpuLimit - _cpuDemand = table.cpuDemand - _cpuUsage = table.cpuUsage - _cpuUtilization = table.cpuUtilization - _cpuActiveTime = table.cpuActiveTime - _cpuIdleTime = table.cpuIdleTime - _cpuStealTime = table.cpuStealTime - _cpuLostTime = table.cpuLostTime - _powerDraw = table.powerDraw - _energyUsage = table.energyUsage - _uptime = table.uptime - _downtime = table.downtime - _bootTime = table.bootTime - _bootTimeAbsolute = table.bootTimeAbsolute - } - - private val _host = host - - override val host: HostInfo = - HostInfo( - host.getUid().toString(), - host.getName(), - "x86", - host.getModel().coreCount, - host.getModel().cpuCapacity, - host.getModel().memoryCapacity, - ) - - override val timestamp: Instant - get() = _timestamp - private var _timestamp = Instant.MIN - - override val timestampAbsolute: Instant - get() = _timestampAbsolute - private var _timestampAbsolute = Instant.MIN - - override val guestsTerminated: Int - get() = _guestsTerminated - private var _guestsTerminated = 0 - - override val guestsRunning: Int - get() = _guestsRunning - private var _guestsRunning = 0 - - override val guestsError: Int - get() = _guestsError - private var _guestsError = 0 - - override val guestsInvalid: Int - get() = _guestsInvalid - private var _guestsInvalid = 0 - - override val cpuLimit: Double - get() = _cpuLimit - private var _cpuLimit = 0.0 - - override val cpuUsage: Double - get() = _cpuUsage - private var _cpuUsage = 0.0 - - override val cpuDemand: Double - get() = _cpuDemand - private var _cpuDemand = 0.0 - - override val cpuUtilization: Double - get() = _cpuUtilization - private var _cpuUtilization = 0.0 - - override val cpuActiveTime: Long - get() = _cpuActiveTime - previousCpuActiveTime - private var _cpuActiveTime = 0L - private var previousCpuActiveTime = 0L - - override val cpuIdleTime: Long - get() = _cpuIdleTime - previousCpuIdleTime - private var _cpuIdleTime = 0L - private var previousCpuIdleTime = 0L - - override val cpuStealTime: Long - get() = _cpuStealTime - previousCpuStealTime - private var _cpuStealTime = 0L - private var previousCpuStealTime = 0L - - override val cpuLostTime: Long - get() = _cpuLostTime - previousCpuLostTime - private var _cpuLostTime = 0L - private var previousCpuLostTime = 0L - - override val powerDraw: Double - get() = _powerDraw - private var _powerDraw = 0.0 - - override val energyUsage: Double - get() = _energyUsage - previousEnergyUsage - private var _energyUsage = 0.0 - private var previousEnergyUsage = 0.0 - - override val uptime: Long - get() = _uptime - previousUptime - private var _uptime = 0L - private var previousUptime = 0L - - override val downtime: Long - get() = _downtime - previousDowntime - private var _downtime = 0L - private var previousDowntime = 0L - - override val bootTime: Instant? - get() = _bootTime - private var _bootTime: Instant? = null - - override val bootTimeAbsolute: Instant? - get() = _bootTimeAbsolute - private var _bootTimeAbsolute: Instant? = null - - /** - * Record the next cycle. - */ - override fun record(now: Instant) { - val hostCpuStats = _host.getCpuStats() - val hostSysStats = _host.getSystemStats() - - _timestamp = now - _timestampAbsolute = now + startTime - - _guestsTerminated = hostSysStats.guestsTerminated - _guestsRunning = hostSysStats.guestsRunning - _guestsError = hostSysStats.guestsError - _guestsInvalid = hostSysStats.guestsInvalid - _cpuLimit = hostCpuStats.capacity - _cpuDemand = hostCpuStats.demand - _cpuUsage = hostCpuStats.usage - _cpuUtilization = hostCpuStats.utilization - _cpuActiveTime = hostCpuStats.activeTime - _cpuIdleTime = hostCpuStats.idleTime - _cpuStealTime = hostCpuStats.stealTime - _cpuLostTime = hostCpuStats.lostTime - _powerDraw = hostSysStats.powerDraw - _energyUsage = hostSysStats.energyUsage - _uptime = hostSysStats.uptime.toMillis() - _downtime = hostSysStats.downtime.toMillis() - _bootTime = hostSysStats.bootTime - _bootTime = hostSysStats.bootTime + startTime - } - - /** - * Finish the aggregation for this cycle. - */ - override fun reset() { - // Reset intermediate state for next aggregation - previousCpuActiveTime = _cpuActiveTime - previousCpuIdleTime = _cpuIdleTime - previousCpuStealTime = _cpuStealTime - previousCpuLostTime = _cpuLostTime - previousEnergyUsage = _energyUsage - previousUptime = _uptime - previousDowntime = _downtime - - _guestsTerminated = 0 - _guestsRunning = 0 - _guestsError = 0 - _guestsInvalid = 0 - - _cpuLimit = 0.0 - _cpuUsage = 0.0 - _cpuDemand = 0.0 - _cpuUtilization = 0.0 - - _powerDraw = 0.0 - _energyUsage = 0.0 - } -} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReader.kt deleted file mode 100644 index cd2b2d2c..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReader.kt +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.simulator.telemetry.table - -import org.opendc.trace.util.parquet.exporter.Exportable -import java.time.Instant - -/** - * An interface that is used to read a row of a host trace entry. - */ -public interface PowerSourceTableReader : Exportable { - public fun copy(): PowerSourceTableReader - - public fun setValues(table: PowerSourceTableReader) - - public fun record(now: Instant) - - public fun reset() - - /** - * The timestamp of the current entry of the reader relative to the start of the workload. - */ - public val timestamp: Instant - - /** - * The timestamp of the current entry of the reader. - */ - public val timestampAbsolute: Instant - - /** - * The number of connected hosts - */ - public val hostsConnected: Int - - /** - * The current power draw of the host in W. - */ - public val powerDraw: Double - - /** - * The total energy consumption of the host since last sample in J. - */ - public val energyUsage: Double - - /** - * The current carbon intensity of the host in gCO2 / kW. - */ - public val carbonIntensity: Double - - /** - * The current carbon emission since the last deadline in g. - */ - public val carbonEmission: Double -} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReaderImpl.kt deleted file mode 100644 index 6a44d1ea..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReaderImpl.kt +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2024 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.simulator.telemetry.table - -import org.opendc.simulator.compute.power.SimPowerSource -import java.time.Duration -import java.time.Instant - -/** - * An aggregator for task metrics before they are reported. - */ -public class PowerSourceTableReaderImpl( - powerSource: SimPowerSource, - private val startTime: Duration = Duration.ofMillis(0), -) : PowerSourceTableReader { - override fun copy(): PowerSourceTableReader { - val newPowerSourceTable = - PowerSourceTableReaderImpl( - powerSource, - ) - newPowerSourceTable.setValues(this) - - return newPowerSourceTable - } - - override fun setValues(table: PowerSourceTableReader) { - _timestamp = table.timestamp - _timestampAbsolute = table.timestampAbsolute - - _hostsConnected = table.hostsConnected - _powerDraw = table.powerDraw - _energyUsage = table.energyUsage - _carbonIntensity = table.carbonIntensity - _carbonEmission = table.carbonEmission - } - - private val powerSource = powerSource - - private var _timestamp = Instant.MIN - override val timestamp: Instant - get() = _timestamp - - private var _timestampAbsolute = Instant.MIN - override val timestampAbsolute: Instant - get() = _timestampAbsolute - - override val hostsConnected: Int - get() = _hostsConnected - private var _hostsConnected: Int = 0 - - override val powerDraw: Double - get() = _powerDraw - private var _powerDraw = 0.0 - - override val energyUsage: Double - get() = _energyUsage - previousEnergyUsage - private var _energyUsage = 0.0 - private var previousEnergyUsage = 0.0 - - override val carbonIntensity: Double - get() = _carbonIntensity - private var _carbonIntensity = 0.0 - - override val carbonEmission: Double - get() = _carbonEmission - previousCarbonEmission - private var _carbonEmission = 0.0 - private var previousCarbonEmission = 0.0 - - /** - * Record the next cycle. - */ - override fun record(now: Instant) { - _timestamp = now - _timestampAbsolute = now + startTime - - _hostsConnected = 0 - - powerSource.updateCounters() - _powerDraw = powerSource.powerDraw - _energyUsage = powerSource.energyUsage - _carbonIntensity = powerSource.carbonIntensity - _carbonEmission = powerSource.carbonEmission - } - - /** - * Finish the aggregation for this cycle. - */ - override fun reset() { - previousEnergyUsage = _energyUsage - previousCarbonEmission = _carbonEmission - - _hostsConnected = 0 - _powerDraw = 0.0 - _energyUsage = 0.0 - _carbonIntensity = 0.0 - _carbonEmission = 0.0 - } -} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceData.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceData.kt deleted file mode 100644 index 16c38297..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceData.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.simulator.telemetry.table - -import java.time.Instant - -/** - * A trace entry for the compute service. - */ -public data class ServiceData( - val timestamp: Instant, - val hostsUp: Int, - val hostsDown: Int, - val tasksTotal: Int, - val tasksPending: Int, - val tasksActive: Int, - val attemptsSuccess: Int, - val attemptsTerminated: Int, -) - -/** - * Convert a [ServiceTableReader] into a persistent object. - */ -public fun ServiceTableReader.toServiceData(): ServiceData { - return ServiceData( - timestamp, - hostsUp, - hostsDown, - tasksTotal, - tasksPending, - tasksActive, - attemptsSuccess, - attemptsFailure, - ) -} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceTableReader.kt deleted file mode 100644 index c8cc765a..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceTableReader.kt +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.simulator.telemetry.table - -import org.opendc.trace.util.parquet.exporter.Exportable -import java.time.Instant - -/** - * An interface that is used to read a row of a service trace entry. - */ -public interface ServiceTableReader : Exportable { - public fun copy(): ServiceTableReader - - public fun setValues(table: ServiceTableReader) - - public fun record(now: Instant) - - /** - * The timestamp of the current entry of the reader. - */ - public val timestamp: Instant - - /** - * The timestamp of the current entry of the reader. - */ - public val timestampAbsolute: Instant - - /** - * The number of hosts that are up at this instant. - */ - public val hostsUp: Int - - /** - * The number of hosts that are down at this instant. - */ - public val hostsDown: Int - - /** - * The number of tasks that are registered with the compute service. - */ - public val tasksTotal: Int - - /** - * The number of tasks that are pending to be scheduled. - */ - public val tasksPending: Int - - /** - * The number of tasks that are currently active. - */ - public val tasksActive: Int - - /** - * The number of tasks that completed the tasks successfully - */ - public val tasksCompleted: Int - - /** - * The number of tasks that failed more times than allowed and are thus terminated - */ - public val tasksTerminated: Int - - /** - * The scheduling attempts that were successful. - */ - public val attemptsSuccess: Int - - /** - * The scheduling attempts that were unsuccessful due to client error. - */ - public val attemptsFailure: Int -} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceTableReaderImpl.kt deleted file mode 100644 index 52a25021..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceTableReaderImpl.kt +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2024 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.simulator.telemetry.table - -import org.opendc.compute.simulator.service.ComputeService -import java.time.Duration -import java.time.Instant - -/** - * An aggregator for service metrics before they are reported. - */ -public class ServiceTableReaderImpl( - private val service: ComputeService, - private val startTime: Duration = Duration.ofMillis(0), -) : ServiceTableReader { - override fun copy(): ServiceTableReader { - val newServiceTable = - ServiceTableReaderImpl( - service, - ) - newServiceTable.setValues(this) - - return newServiceTable - } - - override fun setValues(table: ServiceTableReader) { - _timestamp = table.timestamp - _timestampAbsolute = table.timestampAbsolute - - _hostsUp = table.hostsUp - _hostsDown = table.hostsDown - _tasksTotal = table.tasksTotal - _tasksPending = table.tasksPending - _tasksActive = table.tasksActive - _tasksCompleted = table.tasksCompleted - _tasksTerminated = table.tasksTerminated - _attemptsSuccess = table.attemptsSuccess - _attemptsFailure = table.attemptsFailure - } - - private var _timestamp: Instant = Instant.MIN - override val timestamp: Instant - get() = _timestamp - - private var _timestampAbsolute: Instant = Instant.MIN - override val timestampAbsolute: Instant - get() = _timestampAbsolute - - override val hostsUp: Int - get() = _hostsUp - private var _hostsUp = 0 - - override val hostsDown: Int - get() = _hostsDown - private var _hostsDown = 0 - - override val tasksTotal: Int - get() = _tasksTotal - private var _tasksTotal = 0 - - override val tasksPending: Int - get() = _tasksPending - private var _tasksPending = 0 - - override val tasksCompleted: Int - get() = _tasksCompleted - private var _tasksCompleted = 0 - - override val tasksActive: Int - get() = _tasksActive - private var _tasksActive = 0 - - override val tasksTerminated: Int - get() = _tasksTerminated - private var _tasksTerminated = 0 - - override val attemptsSuccess: Int - get() = _attemptsSuccess - private var _attemptsSuccess = 0 - - override val attemptsFailure: Int - get() = _attemptsFailure - private var _attemptsFailure = 0 - - /** - * Record the next cycle. - */ - override fun record(now: Instant) { - _timestamp = now - _timestampAbsolute = now + startTime - - val stats = service.getSchedulerStats() - _hostsUp = stats.hostsAvailable - _hostsDown = stats.hostsUnavailable - _tasksTotal = stats.tasksTotal - _tasksPending = stats.tasksPending - _tasksCompleted = stats.tasksCompleted - _tasksActive = stats.tasksActive - _tasksTerminated = stats.tasksTerminated - _attemptsSuccess = stats.attemptsSuccess.toInt() - _attemptsFailure = stats.attemptsFailure.toInt() - } -} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskInfo.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskInfo.kt deleted file mode 100644 index 6ff56541..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskInfo.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.simulator.telemetry.table - -/** - * Static information about a task exposed to the telemetry service. - */ -public data class TaskInfo( - val id: String, - val name: String, - val type: String, - val arch: String, - val cpuCount: Int, - val memCapacity: Long, -) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskTableReader.kt deleted file mode 100644 index 0a752e75..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskTableReader.kt +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.simulator.telemetry.table - -import org.opendc.compute.api.TaskState -import org.opendc.compute.simulator.telemetry.parquet.DfltTaskExportColumns -import org.opendc.trace.util.parquet.exporter.Exportable -import java.time.Instant - -/** - * An interface that is used to read a row of a task trace entry. - */ -public interface TaskTableReader : Exportable { - public fun copy(): TaskTableReader - - public fun setValues(table: TaskTableReader) - - public fun record(now: Instant) - - public fun reset() - - /** - * The timestamp of the current entry of the reader relative to the start of the workload. - */ - public val timestamp: Instant - - /** - * The timestamp of the current entry of the reader. - */ - public val timestampAbsolute: Instant - - /** - * The [TaskInfo] of the task to which the row belongs to. - */ - public val taskInfo: TaskInfo - - /** - * The [HostInfo] of the host on which the task is hosted or `null` if it has no host. - */ - public val host: HostInfo? - - /** - * The uptime of the host since last time in ms. - */ - public val uptime: Long - - /** - * The downtime of the host since last time in ms. - */ - public val downtime: Long - - /** - * The [Instant] at which the task was enqueued for the scheduler. - */ - public val provisionTime: Instant? - - /** - * The [Instant] at which the task booted relative to the start of the workload. - */ - public val bootTime: Instant? - - /** - * The [Instant] at which the task booted. - */ - public val bootTimeAbsolute: Instant? - - /** - * The [Instant] at which the task booted relative to the start of the workload. - */ - public val creationTime: Instant? - - /** - * The [Instant] at which the task booted relative to the start of the workload. - */ - public val finishTime: Instant? - - /** - * The capacity of the CPUs of Host on which the task is running (in MHz). - */ - public val cpuLimit: Double - - /** - * The CPU given to this task (in MHz). - */ - public val cpuUsage: Double - - /** - * The CPU demanded by this task (in MHz). - */ - public val cpuDemand: Double - - /** - * The duration (in seconds) that a CPU was active in the task. - */ - public val cpuActiveTime: Long - - /** - * The duration (in seconds) that a CPU was idle in the task. - */ - public val cpuIdleTime: Long - - /** - * The duration (in seconds) that a vCPU wanted to run, but no capacity was available. - */ - public val cpuStealTime: Long - - /** - * The duration (in seconds) of CPU time that was lost due to interference. - */ - public val cpuLostTime: Long - - /** - * The state of the task - */ - public val taskState: TaskState? -} - -// Loads the default export fields for deserialization whenever this file is loaded. -private val _ignore = DfltTaskExportColumns diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskTableReaderImpl.kt deleted file mode 100644 index edcc8b20..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskTableReaderImpl.kt +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2024 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.simulator.telemetry.table - -import org.opendc.compute.api.TaskState -import org.opendc.compute.simulator.host.SimHost -import org.opendc.compute.simulator.service.ComputeService -import org.opendc.compute.simulator.service.ServiceTask -import java.time.Duration -import java.time.Instant - -/** - * An aggregator for task metrics before they are reported. - */ -public class TaskTableReaderImpl( - private val service: ComputeService, - private val task: ServiceTask, - private val startTime: Duration = Duration.ofMillis(0), -) : TaskTableReader { - override fun copy(): TaskTableReader { - val newTaskTable = - TaskTableReaderImpl( - service, - task, - ) - newTaskTable.setValues(this) - - return newTaskTable - } - - override fun setValues(table: TaskTableReader) { - host = table.host - - _timestamp = table.timestamp - _timestampAbsolute = table.timestampAbsolute - - _cpuLimit = table.cpuLimit - _cpuDemand = table.cpuDemand - _cpuUsage = table.cpuUsage - _cpuActiveTime = table.cpuActiveTime - _cpuIdleTime = table.cpuIdleTime - _cpuStealTime = table.cpuStealTime - _cpuLostTime = table.cpuLostTime - _uptime = table.uptime - _downtime = table.downtime - _provisionTime = table.provisionTime - _bootTime = table.bootTime - _bootTimeAbsolute = table.bootTimeAbsolute - - _creationTime = table.creationTime - _finishTime = table.finishTime - - _taskState = table.taskState - } - - /** - * The static information about this task. - */ - override val taskInfo: TaskInfo = - TaskInfo( - task.uid.toString(), - task.name, - "vm", - "x86", - task.flavor.coreCount, - task.flavor.memorySize, - ) - - /** - * The [HostInfo] of the host on which the task is hosted. - */ - override var host: HostInfo? = null - private var _host: SimHost? = null - - private var _timestamp = Instant.MIN - override val timestamp: Instant - get() = _timestamp - - private var _timestampAbsolute = Instant.MIN - override val timestampAbsolute: Instant - get() = _timestampAbsolute - - override val uptime: Long - get() = _uptime - previousUptime - private var _uptime: Long = 0 - private var previousUptime = 0L - - override val downtime: Long - get() = _downtime - previousDowntime - private var _downtime: Long = 0 - private var previousDowntime = 0L - - override val provisionTime: Instant? - get() = _provisionTime - private var _provisionTime: Instant? = null - - override val bootTime: Instant? - get() = _bootTime - private var _bootTime: Instant? = null - - override val creationTime: Instant? - get() = _creationTime - private var _creationTime: Instant? = null - - override val finishTime: Instant? - get() = _finishTime - private var _finishTime: Instant? = null - - override val cpuLimit: Double - get() = _cpuLimit - private var _cpuLimit = 0.0 - - override val cpuUsage: Double - get() = _cpuUsage - private var _cpuUsage = 0.0 - - override val cpuDemand: Double - get() = _cpuDemand - private var _cpuDemand = 0.0 - - override val cpuActiveTime: Long - get() = _cpuActiveTime - previousCpuActiveTime - private var _cpuActiveTime = 0L - private var previousCpuActiveTime = 0L - - override val cpuIdleTime: Long - get() = _cpuIdleTime - previousCpuIdleTime - private var _cpuIdleTime = 0L - private var previousCpuIdleTime = 0L - - override val cpuStealTime: Long - get() = _cpuStealTime - previousCpuStealTime - private var _cpuStealTime = 0L - private var previousCpuStealTime = 0L - - override val cpuLostTime: Long - get() = _cpuLostTime - previousCpuLostTime - private var _cpuLostTime = 0L - private var previousCpuLostTime = 0L - - override val bootTimeAbsolute: Instant? - get() = _bootTimeAbsolute - private var _bootTimeAbsolute: Instant? = null - - override val taskState: TaskState? - get() = _taskState - private var _taskState: TaskState? = null - - /** - * Record the next cycle. - */ - override fun record(now: Instant) { - val newHost = service.lookupHost(task) - if (newHost != null && newHost.getUid() != _host?.getUid()) { - _host = newHost - host = - HostInfo( - newHost.getUid().toString(), - newHost.getName(), - "x86", - newHost.getModel().coreCount, - newHost.getModel().cpuCapacity, - newHost.getModel().memoryCapacity, - ) - } - - val cpuStats = _host?.getCpuStats(task) - val sysStats = _host?.getSystemStats(task) - - _timestamp = now - _timestampAbsolute = now + startTime - - _cpuLimit = cpuStats?.capacity ?: 0.0 - _cpuDemand = cpuStats?.demand ?: 0.0 - _cpuUsage = cpuStats?.usage ?: 0.0 - _cpuActiveTime = cpuStats?.activeTime ?: _cpuActiveTime - _cpuIdleTime = cpuStats?.idleTime ?: _cpuIdleTime - _cpuStealTime = cpuStats?.stealTime ?: _cpuStealTime - _cpuLostTime = cpuStats?.lostTime ?: _cpuLostTime - _uptime = sysStats?.uptime?.toMillis() ?: _uptime - _downtime = sysStats?.downtime?.toMillis() ?: _downtime - _provisionTime = task.launchedAt - _bootTime = sysStats?.bootTime ?: _bootTime - _creationTime = task.createdAt - _finishTime = task.finishedAt - - _taskState = task.state - - if (sysStats != null) { - _bootTimeAbsolute = sysStats.bootTime + startTime - } else { - _bootTimeAbsolute = null - } - } - - /** - * Finish the aggregation for this cycle. - */ - override fun reset() { - previousUptime = _uptime - previousDowntime = _downtime - previousCpuActiveTime = _cpuActiveTime - previousCpuIdleTime = _cpuIdleTime - previousCpuStealTime = _cpuStealTime - previousCpuLostTime = _cpuLostTime - - _host = null - _cpuLimit = 0.0 - } -} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryInfo.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryInfo.kt new file mode 100644 index 00000000..7dac5920 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryInfo.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.battery + +public data class BatteryInfo( + val name: String, + val clusterName: String, + val arch: String, + val capacity: Double, +) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryTableReader.kt new file mode 100644 index 00000000..6747d676 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryTableReader.kt @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.battery + +import org.opendc.simulator.compute.power.batteries.BatteryState +import org.opendc.trace.util.parquet.exporter.Exportable +import java.time.Instant + +/** + * An interface that is used to read a row of a host trace entry. + */ +public interface BatteryTableReader : Exportable { + public fun copy(): BatteryTableReader + + public fun setValues(table: BatteryTableReader) + + public fun record(now: Instant) + + public fun reset() + + public val batteryInfo: BatteryInfo + + /** + * The timestamp of the current entry of the reader relative to the start of the workload. + */ + public val timestamp: Instant + + /** + * The timestamp of the current entry of the reader. + */ + public val timestampAbsolute: Instant + + /** + * The number of connected hosts + */ + public val hostsConnected: Int + + /** + * The current power draw of the host in W. + */ + public val powerDraw: Double + + /** + * The current power draw of the host in W. + */ + public val energyUsage: Double + + public val batteryState: BatteryState + + public val charge: Double + + public val capacity: Double +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryTableReaderImpl.kt new file mode 100644 index 00000000..7b666c30 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/battery/BatteryTableReaderImpl.kt @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2024 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.battery + +import org.opendc.simulator.compute.power.batteries.BatteryState +import org.opendc.simulator.compute.power.batteries.SimBattery +import java.time.Duration +import java.time.Instant + +/** + * An aggregator for task metrics before they are reported. + */ +public class BatteryTableReaderImpl( + private val battery: SimBattery, + private val startTime: Duration = Duration.ofMillis(0), +) : BatteryTableReader { + override fun copy(): BatteryTableReader { + val newPowerSourceTable = + BatteryTableReaderImpl( + battery, + ) + newPowerSourceTable.setValues(this) + + return newPowerSourceTable + } + + override fun setValues(table: BatteryTableReader) { + _timestamp = table.timestamp + _timestampAbsolute = table.timestampAbsolute + + _hostsConnected = table.hostsConnected + _powerDraw = table.powerDraw + _energyUsage = table.energyUsage + _charge = table.charge + _capacity = table.capacity + _batteryState = table.batteryState + } + + public override val batteryInfo: BatteryInfo = + BatteryInfo( + battery.name, + battery.clusterName, + "XXX", + battery.capacity, + ) + + private var _timestamp = Instant.MIN + override val timestamp: Instant + get() = _timestamp + + private var _timestampAbsolute = Instant.MIN + override val timestampAbsolute: Instant + get() = _timestampAbsolute + + override val hostsConnected: Int + get() = _hostsConnected + private var _hostsConnected: Int = 0 + + override val powerDraw: Double + get() = _powerDraw + private var _powerDraw = 0.0 + + override val energyUsage: Double + get() = _energyUsage - previousEnergyUsage + private var _energyUsage = 0.0 + private var previousEnergyUsage = 0.0 + + override val charge: Double + get() = _charge + private var _charge = 0.0 + + override val capacity: Double + get() = _capacity + private var _capacity = 0.0 + + override val batteryState: BatteryState + get() = _batteryState + private var _batteryState = BatteryState.IDLE + + /** + * Record the next cycle. + */ + override fun record(now: Instant) { + _timestamp = now + _timestampAbsolute = now + startTime + + _hostsConnected = 0 + + battery.updateCounters() + _powerDraw = battery.outgoingSupply + _energyUsage = battery.totalEnergyUsage + + _charge = battery.charge + _capacity = battery.capacity + _batteryState = battery.batteryState + } + + /** + * Finish the aggregation for this cycle. + */ + override fun reset() { + previousEnergyUsage = _energyUsage + + _hostsConnected = 0 + _powerDraw = 0.0 + _energyUsage = 0.0 + _charge = 0.0 + _capacity = 0.0 + _batteryState = BatteryState.IDLE + } +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostInfo.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostInfo.kt new file mode 100644 index 00000000..b3b4ede8 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostInfo.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.host + +/** + * Information about a host exposed to the telemetry service. + */ +public data class HostInfo( + val name: String, + val clusterName: String, + val arch: String, + val coreCount: Int, + val coreSpeed: Double, + val memCapacity: Long, +) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReader.kt new file mode 100644 index 00000000..1d3d46d9 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReader.kt @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.host + +import org.opendc.trace.util.parquet.exporter.Exportable +import java.time.Instant + +/** + * An interface that is used to read a row of a host trace entry. + */ +public interface HostTableReader : Exportable { + public fun copy(): HostTableReader + + public fun setValues(table: HostTableReader) + + public fun record(now: Instant) + + public fun reset() + + /** + * The [HostInfo] of the host to which the row belongs to. + */ + public val hostInfo: HostInfo + + /** + * The timestamp of the current entry of the reader relative to the start of the workload. + */ + public val timestamp: Instant + + /** + * The timestamp of the current entry of the reader. + */ + public val timestampAbsolute: Instant + + /** + * The number of guests that are in a terminated state. + */ + public val guestsTerminated: Int + + /** + * The number of guests that are in a running state. + */ + public val guestsRunning: Int + + /** + * The number of guests that are in an error state. + */ + public val guestsError: Int + + /** + * The number of guests that are in an unknown state. + */ + public val guestsInvalid: Int + + /** + * The capacity of the CPUs in the host (in MHz). + */ + public val cpuLimit: Double + + /** + * The usage of all CPUs in the host (in MHz). + */ + public val cpuUsage: Double + + /** + * The demand of all vCPUs of the guests (in MHz) + */ + public val cpuDemand: Double + + /** + * The CPU utilization of the host. + */ + public val cpuUtilization: Double + + /** + * The duration (in ms) that a CPU was active in the host. + */ + public val cpuActiveTime: Long + + /** + * The duration (in ms) that a CPU was idle in the host. + */ + public val cpuIdleTime: Long + + /** + * The duration (in ms) that a vCPU wanted to run, but no capacity was available. + */ + public val cpuStealTime: Long + + /** + * The duration (in ms) of CPU time that was lost due to interference. + */ + public val cpuLostTime: Long + + /** + * The current power draw of the host in W. + */ + public val powerDraw: Double + + /** + * The total energy consumption of the host since last sample in J. + */ + public val energyUsage: Double + + /** + * The uptime of the host since last time in ms. + */ + public val uptime: Long + + /** + * The downtime of the host since last time in ms. + */ + public val downtime: Long + + /** + * The [Instant] at which the host booted relative to the start of the workload. + */ + public val bootTime: Instant? + + /** + * The [Instant] at which the host booted. + */ + public val bootTimeAbsolute: Instant? +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReaderImpl.kt new file mode 100644 index 00000000..5babb864 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReaderImpl.kt @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2024 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.host + +import org.opendc.compute.simulator.host.SimHost +import java.time.Duration +import java.time.Instant + +/** + * An aggregator for host metrics before they are reported. + */ +public class HostTableReaderImpl( + private val host: SimHost, + private val startTime: Duration = Duration.ofMillis(0), +) : HostTableReader { + override fun copy(): HostTableReader { + val newHostTable = + HostTableReaderImpl(host) + newHostTable.setValues(this) + + return newHostTable + } + + override fun setValues(table: HostTableReader) { + _timestamp = table.timestamp + _timestampAbsolute = table.timestampAbsolute + + _guestsTerminated = table.guestsTerminated + _guestsRunning = table.guestsRunning + _guestsError = table.guestsError + _guestsInvalid = table.guestsInvalid + _cpuLimit = table.cpuLimit + _cpuDemand = table.cpuDemand + _cpuUsage = table.cpuUsage + _cpuUtilization = table.cpuUtilization + _cpuActiveTime = table.cpuActiveTime + _cpuIdleTime = table.cpuIdleTime + _cpuStealTime = table.cpuStealTime + _cpuLostTime = table.cpuLostTime + _powerDraw = table.powerDraw + _energyUsage = table.energyUsage + _uptime = table.uptime + _downtime = table.downtime + _bootTime = table.bootTime + _bootTimeAbsolute = table.bootTimeAbsolute + } + + override val hostInfo: HostInfo = + HostInfo( + host.getName(), + host.getClusterName(), + "x86", + host.getModel().coreCount, + host.getModel().cpuCapacity, + host.getModel().memoryCapacity, + ) + + override val timestamp: Instant + get() = _timestamp + private var _timestamp = Instant.MIN + + override val timestampAbsolute: Instant + get() = _timestampAbsolute + private var _timestampAbsolute = Instant.MIN + + override val guestsTerminated: Int + get() = _guestsTerminated + private var _guestsTerminated = 0 + + override val guestsRunning: Int + get() = _guestsRunning + private var _guestsRunning = 0 + + override val guestsError: Int + get() = _guestsError + private var _guestsError = 0 + + override val guestsInvalid: Int + get() = _guestsInvalid + private var _guestsInvalid = 0 + + override val cpuLimit: Double + get() = _cpuLimit + private var _cpuLimit = 0.0 + + override val cpuUsage: Double + get() = _cpuUsage + private var _cpuUsage = 0.0 + + override val cpuDemand: Double + get() = _cpuDemand + private var _cpuDemand = 0.0 + + override val cpuUtilization: Double + get() = _cpuUtilization + private var _cpuUtilization = 0.0 + + override val cpuActiveTime: Long + get() = _cpuActiveTime - previousCpuActiveTime + private var _cpuActiveTime = 0L + private var previousCpuActiveTime = 0L + + override val cpuIdleTime: Long + get() = _cpuIdleTime - previousCpuIdleTime + private var _cpuIdleTime = 0L + private var previousCpuIdleTime = 0L + + override val cpuStealTime: Long + get() = _cpuStealTime - previousCpuStealTime + private var _cpuStealTime = 0L + private var previousCpuStealTime = 0L + + override val cpuLostTime: Long + get() = _cpuLostTime - previousCpuLostTime + private var _cpuLostTime = 0L + private var previousCpuLostTime = 0L + + override val powerDraw: Double + get() = _powerDraw + private var _powerDraw = 0.0 + + override val energyUsage: Double + get() = _energyUsage - previousEnergyUsage + private var _energyUsage = 0.0 + private var previousEnergyUsage = 0.0 + + override val uptime: Long + get() = _uptime - previousUptime + private var _uptime = 0L + private var previousUptime = 0L + + override val downtime: Long + get() = _downtime - previousDowntime + private var _downtime = 0L + private var previousDowntime = 0L + + override val bootTime: Instant? + get() = _bootTime + private var _bootTime: Instant? = null + + override val bootTimeAbsolute: Instant? + get() = _bootTimeAbsolute + private var _bootTimeAbsolute: Instant? = null + + /** + * Record the next cycle. + */ + override fun record(now: Instant) { + val hostCpuStats = host.getCpuStats() + val hostSysStats = host.getSystemStats() + + _timestamp = now + _timestampAbsolute = now + startTime + + _guestsTerminated = hostSysStats.guestsTerminated + _guestsRunning = hostSysStats.guestsRunning + _guestsError = hostSysStats.guestsError + _guestsInvalid = hostSysStats.guestsInvalid + _cpuLimit = hostCpuStats.capacity + _cpuDemand = hostCpuStats.demand + _cpuUsage = hostCpuStats.usage + _cpuUtilization = hostCpuStats.utilization + _cpuActiveTime = hostCpuStats.activeTime + _cpuIdleTime = hostCpuStats.idleTime + _cpuStealTime = hostCpuStats.stealTime + _cpuLostTime = hostCpuStats.lostTime + _powerDraw = hostSysStats.powerDraw + _energyUsage = hostSysStats.energyUsage + _uptime = hostSysStats.uptime.toMillis() + _downtime = hostSysStats.downtime.toMillis() + _bootTime = hostSysStats.bootTime + _bootTime = hostSysStats.bootTime + startTime + } + + /** + * Finish the aggregation for this cycle. + */ + override fun reset() { + // Reset intermediate state for next aggregation + previousCpuActiveTime = _cpuActiveTime + previousCpuIdleTime = _cpuIdleTime + previousCpuStealTime = _cpuStealTime + previousCpuLostTime = _cpuLostTime + previousEnergyUsage = _energyUsage + previousUptime = _uptime + previousDowntime = _downtime + + _guestsTerminated = 0 + _guestsRunning = 0 + _guestsError = 0 + _guestsInvalid = 0 + + _cpuLimit = 0.0 + _cpuUsage = 0.0 + _cpuDemand = 0.0 + _cpuUtilization = 0.0 + + _powerDraw = 0.0 + _energyUsage = 0.0 + } +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceInfo.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceInfo.kt new file mode 100644 index 00000000..6b558b72 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceInfo.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.powerSource + +public data class PowerSourceInfo( + val name: String, + val clusterName: String, + val arch: String, + val capacity: Double, +) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceTableReader.kt new file mode 100644 index 00000000..ac69d8a5 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceTableReader.kt @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.powerSource + +import org.opendc.trace.util.parquet.exporter.Exportable +import java.time.Instant + +/** + * An interface that is used to read a row of a host trace entry. + */ +public interface PowerSourceTableReader : Exportable { + public fun copy(): PowerSourceTableReader + + public fun setValues(table: PowerSourceTableReader) + + public fun record(now: Instant) + + public fun reset() + + public val powerSourceInfo: PowerSourceInfo + + /** + * The timestamp of the current entry of the reader relative to the start of the workload. + */ + public val timestamp: Instant + + /** + * The timestamp of the current entry of the reader. + */ + public val timestampAbsolute: Instant + + /** + * The number of connected hosts + */ + public val hostsConnected: Int + + /** + * The current power draw of the host in W. + */ + public val powerDraw: Double + + /** + * The total energy consumption of the host since last sample in J. + */ + public val energyUsage: Double + + /** + * The current carbon intensity of the host in gCO2 / kW. + */ + public val carbonIntensity: Double + + /** + * The current carbon emission since the last deadline in g. + */ + public val carbonEmission: Double +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceTableReaderImpl.kt new file mode 100644 index 00000000..9779f27a --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/powerSource/PowerSourceTableReaderImpl.kt @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2024 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.powerSource + +import org.opendc.simulator.compute.power.SimPowerSource +import java.time.Duration +import java.time.Instant + +/** + * An aggregator for task metrics before they are reported. + */ +public class PowerSourceTableReaderImpl( + private val powerSource: SimPowerSource, + private val startTime: Duration = Duration.ofMillis(0), +) : PowerSourceTableReader { + override fun copy(): PowerSourceTableReader { + val newPowerSourceTable = + PowerSourceTableReaderImpl( + powerSource, + ) + newPowerSourceTable.setValues(this) + + return newPowerSourceTable + } + + override fun setValues(table: PowerSourceTableReader) { + _timestamp = table.timestamp + _timestampAbsolute = table.timestampAbsolute + + _hostsConnected = table.hostsConnected + _powerDraw = table.powerDraw + _energyUsage = table.energyUsage + _carbonIntensity = table.carbonIntensity + _carbonEmission = table.carbonEmission + } + + public override val powerSourceInfo: PowerSourceInfo = + PowerSourceInfo( + powerSource.name, + powerSource.clusterName, + "XXX", + powerSource.capacity, + ) + + private var _timestamp = Instant.MIN + override val timestamp: Instant + get() = _timestamp + + private var _timestampAbsolute = Instant.MIN + override val timestampAbsolute: Instant + get() = _timestampAbsolute + + override val hostsConnected: Int + get() = _hostsConnected + private var _hostsConnected: Int = 0 + + override val powerDraw: Double + get() = _powerDraw + private var _powerDraw = 0.0 + + override val energyUsage: Double + get() = _energyUsage - previousEnergyUsage + private var _energyUsage = 0.0 + private var previousEnergyUsage = 0.0 + + override val carbonIntensity: Double + get() = _carbonIntensity + private var _carbonIntensity = 0.0 + + override val carbonEmission: Double + get() = _carbonEmission - previousCarbonEmission + private var _carbonEmission = 0.0 + private var previousCarbonEmission = 0.0 + + /** + * Record the next cycle. + */ + override fun record(now: Instant) { + _timestamp = now + _timestampAbsolute = now + startTime + + _hostsConnected = 0 + + powerSource.updateCounters() + _powerDraw = powerSource.powerDraw + _energyUsage = powerSource.energyUsage + _carbonIntensity = powerSource.carbonIntensity + _carbonEmission = powerSource.carbonEmission + } + + /** + * Finish the aggregation for this cycle. + */ + override fun reset() { + previousEnergyUsage = _energyUsage + previousCarbonEmission = _carbonEmission + + _hostsConnected = 0 + _powerDraw = 0.0 + _energyUsage = 0.0 + _carbonIntensity = 0.0 + _carbonEmission = 0.0 + } +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceData.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceData.kt new file mode 100644 index 00000000..970c9d38 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceData.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.service + +import java.time.Instant + +/** + * A trace entry for the compute service. + */ +public data class ServiceData( + val timestamp: Instant, + val hostsUp: Int, + val hostsDown: Int, + val tasksTotal: Int, + val tasksPending: Int, + val tasksActive: Int, + val attemptsSuccess: Int, + val attemptsTerminated: Int, +) + +/** + * Convert a [ServiceTableReader] into a persistent object. + */ +public fun ServiceTableReader.toServiceData(): ServiceData { + return ServiceData( + timestamp, + hostsUp, + hostsDown, + tasksTotal, + tasksPending, + tasksActive, + attemptsSuccess, + attemptsFailure, + ) +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceTableReader.kt new file mode 100644 index 00000000..b84520a5 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceTableReader.kt @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.service + +import org.opendc.trace.util.parquet.exporter.Exportable +import java.time.Instant + +/** + * An interface that is used to read a row of a service trace entry. + */ +public interface ServiceTableReader : Exportable { + public fun copy(): ServiceTableReader + + public fun setValues(table: ServiceTableReader) + + public fun record(now: Instant) + + /** + * The timestamp of the current entry of the reader. + */ + public val timestamp: Instant + + /** + * The timestamp of the current entry of the reader. + */ + public val timestampAbsolute: Instant + + /** + * The number of hosts that are up at this instant. + */ + public val hostsUp: Int + + /** + * The number of hosts that are down at this instant. + */ + public val hostsDown: Int + + /** + * The number of tasks that are registered with the compute service. + */ + public val tasksTotal: Int + + /** + * The number of tasks that are pending to be scheduled. + */ + public val tasksPending: Int + + /** + * The number of tasks that are currently active. + */ + public val tasksActive: Int + + /** + * The number of tasks that completed the tasks successfully + */ + public val tasksCompleted: Int + + /** + * The number of tasks that failed more times than allowed and are thus terminated + */ + public val tasksTerminated: Int + + /** + * The scheduling attempts that were successful. + */ + public val attemptsSuccess: Int + + /** + * The scheduling attempts that were unsuccessful due to client error. + */ + public val attemptsFailure: Int +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceTableReaderImpl.kt new file mode 100644 index 00000000..daa04ba3 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/service/ServiceTableReaderImpl.kt @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2024 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.service + +import org.opendc.compute.simulator.service.ComputeService +import java.time.Duration +import java.time.Instant + +/** + * An aggregator for service metrics before they are reported. + */ +public class ServiceTableReaderImpl( + private val service: ComputeService, + private val startTime: Duration = Duration.ofMillis(0), +) : ServiceTableReader { + override fun copy(): ServiceTableReader { + val newServiceTable = + ServiceTableReaderImpl( + service, + ) + newServiceTable.setValues(this) + + return newServiceTable + } + + override fun setValues(table: ServiceTableReader) { + _timestamp = table.timestamp + _timestampAbsolute = table.timestampAbsolute + + _hostsUp = table.hostsUp + _hostsDown = table.hostsDown + _tasksTotal = table.tasksTotal + _tasksPending = table.tasksPending + _tasksActive = table.tasksActive + _tasksCompleted = table.tasksCompleted + _tasksTerminated = table.tasksTerminated + _attemptsSuccess = table.attemptsSuccess + _attemptsFailure = table.attemptsFailure + } + + private var _timestamp: Instant = Instant.MIN + override val timestamp: Instant + get() = _timestamp + + private var _timestampAbsolute: Instant = Instant.MIN + override val timestampAbsolute: Instant + get() = _timestampAbsolute + + override val hostsUp: Int + get() = _hostsUp + private var _hostsUp = 0 + + override val hostsDown: Int + get() = _hostsDown + private var _hostsDown = 0 + + override val tasksTotal: Int + get() = _tasksTotal + private var _tasksTotal = 0 + + override val tasksPending: Int + get() = _tasksPending + private var _tasksPending = 0 + + override val tasksCompleted: Int + get() = _tasksCompleted + private var _tasksCompleted = 0 + + override val tasksActive: Int + get() = _tasksActive + private var _tasksActive = 0 + + override val tasksTerminated: Int + get() = _tasksTerminated + private var _tasksTerminated = 0 + + override val attemptsSuccess: Int + get() = _attemptsSuccess + private var _attemptsSuccess = 0 + + override val attemptsFailure: Int + get() = _attemptsFailure + private var _attemptsFailure = 0 + + /** + * Record the next cycle. + */ + override fun record(now: Instant) { + _timestamp = now + _timestampAbsolute = now + startTime + + val stats = service.getSchedulerStats() + _hostsUp = stats.hostsAvailable + _hostsDown = stats.hostsUnavailable + _tasksTotal = stats.tasksTotal + _tasksPending = stats.tasksPending + _tasksCompleted = stats.tasksCompleted + _tasksActive = stats.tasksActive + _tasksTerminated = stats.tasksTerminated + _attemptsSuccess = stats.attemptsSuccess.toInt() + _attemptsFailure = stats.attemptsFailure.toInt() + } +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskInfo.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskInfo.kt new file mode 100644 index 00000000..e0b28379 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskInfo.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.task + +/** + * Static information about a task exposed to the telemetry service. + */ +public data class TaskInfo( + val id: String, + val name: String, + val type: String, + val arch: String, + val cpuCount: Int, + val memCapacity: Long, +) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt new file mode 100644 index 00000000..97d8ca88 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2025 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.task + +import org.opendc.compute.api.TaskState +import org.opendc.compute.simulator.telemetry.parquet.DfltTaskExportColumns +import org.opendc.compute.simulator.telemetry.table.host.HostInfo +import org.opendc.trace.util.parquet.exporter.Exportable +import java.time.Instant + +/** + * An interface that is used to read a row of a task trace entry. + */ +public interface TaskTableReader : Exportable { + public fun copy(): TaskTableReader + + public fun setValues(table: TaskTableReader) + + public fun record(now: Instant) + + public fun reset() + + /** + * The timestamp of the current entry of the reader relative to the start of the workload. + */ + public val timestamp: Instant + + /** + * The timestamp of the current entry of the reader. + */ + public val timestampAbsolute: Instant + + /** + * The [TaskInfo] of the task to which the row belongs to. + */ + public val taskInfo: TaskInfo + + /** + * The [HostInfo] of the host on which the task is hosted or `null` if it has no host. + */ + public val host: HostInfo? + + /** + * The uptime of the host since last time in ms. + */ + public val uptime: Long + + /** + * The downtime of the host since last time in ms. + */ + public val downtime: Long + + /** + * The [Instant] at which the task was enqueued for the scheduler. + */ + public val provisionTime: Instant? + + /** + * The [Instant] at which the task booted relative to the start of the workload. + */ + public val bootTime: Instant? + + /** + * The [Instant] at which the task booted. + */ + public val bootTimeAbsolute: Instant? + + /** + * The [Instant] at which the task booted relative to the start of the workload. + */ + public val creationTime: Instant? + + /** + * The [Instant] at which the task booted relative to the start of the workload. + */ + public val finishTime: Instant? + + /** + * The capacity of the CPUs of Host on which the task is running (in MHz). + */ + public val cpuLimit: Double + + /** + * The CPU given to this task (in MHz). + */ + public val cpuUsage: Double + + /** + * The CPU demanded by this task (in MHz). + */ + public val cpuDemand: Double + + /** + * The duration (in seconds) that a CPU was active in the task. + */ + public val cpuActiveTime: Long + + /** + * The duration (in seconds) that a CPU was idle in the task. + */ + public val cpuIdleTime: Long + + /** + * The duration (in seconds) that a vCPU wanted to run, but no capacity was available. + */ + public val cpuStealTime: Long + + /** + * The duration (in seconds) of CPU time that was lost due to interference. + */ + public val cpuLostTime: Long + + /** + * The state of the task + */ + public val taskState: TaskState? +} + +// Loads the default export fields for deserialization whenever this file is loaded. +private val _ignore = DfltTaskExportColumns diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt new file mode 100644 index 00000000..07462b14 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2025 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.telemetry.table.task + +import org.opendc.compute.api.TaskState +import org.opendc.compute.simulator.host.SimHost +import org.opendc.compute.simulator.service.ComputeService +import org.opendc.compute.simulator.service.ServiceTask +import org.opendc.compute.simulator.telemetry.table.host.HostInfo +import java.time.Duration +import java.time.Instant + +/** + * An aggregator for task metrics before they are reported. + */ +public class TaskTableReaderImpl( + private val service: ComputeService, + private val task: ServiceTask, + private val startTime: Duration = Duration.ofMillis(0), +) : TaskTableReader { + override fun copy(): TaskTableReader { + val newTaskTable = + TaskTableReaderImpl( + service, + task, + ) + newTaskTable.setValues(this) + + return newTaskTable + } + + override fun setValues(table: TaskTableReader) { + host = table.host + + _timestamp = table.timestamp + _timestampAbsolute = table.timestampAbsolute + + _cpuLimit = table.cpuLimit + _cpuDemand = table.cpuDemand + _cpuUsage = table.cpuUsage + _cpuActiveTime = table.cpuActiveTime + _cpuIdleTime = table.cpuIdleTime + _cpuStealTime = table.cpuStealTime + _cpuLostTime = table.cpuLostTime + _uptime = table.uptime + _downtime = table.downtime + _provisionTime = table.provisionTime + _bootTime = table.bootTime + _bootTimeAbsolute = table.bootTimeAbsolute + + _creationTime = table.creationTime + _finishTime = table.finishTime + + _taskState = table.taskState + } + + /** + * The static information about this task. + */ + override val taskInfo: TaskInfo = + TaskInfo( + task.uid.toString(), + task.name, + "vm", + "x86", + task.flavor.coreCount, + task.flavor.memorySize, + ) + + /** + * The [HostInfo] of the host on which the task is hosted. + */ + override var host: HostInfo? = null + private var _host: SimHost? = null + + private var _timestamp = Instant.MIN + override val timestamp: Instant + get() = _timestamp + + private var _timestampAbsolute = Instant.MIN + override val timestampAbsolute: Instant + get() = _timestampAbsolute + + override val uptime: Long + get() = _uptime - previousUptime + private var _uptime: Long = 0 + private var previousUptime = 0L + + override val downtime: Long + get() = _downtime - previousDowntime + private var _downtime: Long = 0 + private var previousDowntime = 0L + + override val provisionTime: Instant? + get() = _provisionTime + private var _provisionTime: Instant? = null + + override val bootTime: Instant? + get() = _bootTime + private var _bootTime: Instant? = null + + override val creationTime: Instant? + get() = _creationTime + private var _creationTime: Instant? = null + + override val finishTime: Instant? + get() = _finishTime + private var _finishTime: Instant? = null + + override val cpuLimit: Double + get() = _cpuLimit + private var _cpuLimit = 0.0 + + override val cpuUsage: Double + get() = _cpuUsage + private var _cpuUsage = 0.0 + + override val cpuDemand: Double + get() = _cpuDemand + private var _cpuDemand = 0.0 + + override val cpuActiveTime: Long + get() = _cpuActiveTime - previousCpuActiveTime + private var _cpuActiveTime = 0L + private var previousCpuActiveTime = 0L + + override val cpuIdleTime: Long + get() = _cpuIdleTime - previousCpuIdleTime + private var _cpuIdleTime = 0L + private var previousCpuIdleTime = 0L + + override val cpuStealTime: Long + get() = _cpuStealTime - previousCpuStealTime + private var _cpuStealTime = 0L + private var previousCpuStealTime = 0L + + override val cpuLostTime: Long + get() = _cpuLostTime - previousCpuLostTime + private var _cpuLostTime = 0L + private var previousCpuLostTime = 0L + + override val bootTimeAbsolute: Instant? + get() = _bootTimeAbsolute + private var _bootTimeAbsolute: Instant? = null + + override val taskState: TaskState? + get() = _taskState + private var _taskState: TaskState? = null + + /** + * Record the next cycle. + */ + override fun record(now: Instant) { + val newHost = service.lookupHost(task) + if (newHost != null && newHost.getName() != _host?.getName()) { + _host = newHost + host = + HostInfo( + newHost.getName(), + newHost.getClusterName(), + "x86", + newHost.getModel().coreCount, + newHost.getModel().cpuCapacity, + newHost.getModel().memoryCapacity, + ) + } + + val cpuStats = _host?.getCpuStats(task) + val sysStats = _host?.getSystemStats(task) + + _timestamp = now + _timestampAbsolute = now + startTime + + _cpuLimit = cpuStats?.capacity ?: 0.0 + _cpuDemand = cpuStats?.demand ?: 0.0 + _cpuUsage = cpuStats?.usage ?: 0.0 + _cpuActiveTime = cpuStats?.activeTime ?: _cpuActiveTime + _cpuIdleTime = cpuStats?.idleTime ?: _cpuIdleTime + _cpuStealTime = cpuStats?.stealTime ?: _cpuStealTime + _cpuLostTime = cpuStats?.lostTime ?: _cpuLostTime + _uptime = sysStats?.uptime?.toMillis() ?: _uptime + _downtime = sysStats?.downtime?.toMillis() ?: _downtime + _provisionTime = task.launchedAt + _bootTime = sysStats?.bootTime ?: _bootTime + _creationTime = task.createdAt + _finishTime = task.finishedAt + + _taskState = task.state + + if (sysStats != null) { + _bootTimeAbsolute = sysStats.bootTime + startTime + } else { + _bootTimeAbsolute = null + } + } + + /** + * Finish the aggregation for this cycle. + */ + override fun reset() { + previousUptime = _uptime + previousDowntime = _downtime + previousCpuActiveTime = _cpuActiveTime + previousCpuIdleTime = _cpuIdleTime + previousCpuStealTime = _cpuStealTime + previousCpuLostTime = _cpuLostTime + + _host = null + _cpuLimit = 0.0 + } +} -- cgit v1.2.3