summaryrefslogtreecommitdiff
path: root/opendc-telemetry
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-telemetry')
-rw-r--r--opendc-telemetry/opendc-telemetry-compute/build.gradle.kts1
-rw-r--r--opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt295
-rw-r--r--opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt14
-rw-r--r--opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt44
-rw-r--r--opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/HostAttributes.kt51
-rw-r--r--opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt4
-rw-r--r--opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostInfo.kt28
-rw-r--r--opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt5
-rw-r--r--opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerInfo.kt37
9 files changed, 328 insertions, 151 deletions
diff --git a/opendc-telemetry/opendc-telemetry-compute/build.gradle.kts b/opendc-telemetry/opendc-telemetry-compute/build.gradle.kts
index 6a3de9bc..cd8cb57a 100644
--- a/opendc-telemetry/opendc-telemetry-compute/build.gradle.kts
+++ b/opendc-telemetry/opendc-telemetry-compute/build.gradle.kts
@@ -31,7 +31,6 @@ dependencies {
api(platform(projects.opendcPlatform))
api(projects.opendcTelemetry.opendcTelemetrySdk)
- implementation(projects.opendcCompute.opendcComputeSimulator)
implementation(libs.opentelemetry.semconv)
implementation(libs.kotlin.logging)
}
diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt
index 57d43c60..408d1325 100644
--- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt
+++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt
@@ -22,137 +22,260 @@
package org.opendc.telemetry.compute
+import io.opentelemetry.api.common.AttributeKey
+import io.opentelemetry.api.common.Attributes
import io.opentelemetry.sdk.common.CompletableResultCode
-import io.opentelemetry.sdk.metrics.data.MetricData
+import io.opentelemetry.sdk.metrics.data.*
import io.opentelemetry.sdk.metrics.export.MetricExporter
+import io.opentelemetry.sdk.resources.Resource
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes
-import org.opendc.compute.service.driver.Host
import org.opendc.telemetry.compute.table.HostData
+import org.opendc.telemetry.compute.table.HostInfo
+import org.opendc.telemetry.compute.table.ServerData
+import org.opendc.telemetry.compute.table.ServerInfo
import java.time.Clock
/**
* A [MetricExporter] that redirects data to a [ComputeMonitor] implementation.
*/
-public class ComputeMetricExporter(
- private val clock: Clock,
- private val hosts: Map<String, Host>,
- private val monitor: ComputeMonitor
-) : MetricExporter {
-
+public class ComputeMetricExporter(private val clock: Clock, private val monitor: ComputeMonitor) : MetricExporter {
override fun export(metrics: Collection<MetricData>): CompletableResultCode {
return try {
- reportHostMetrics(metrics)
reportServiceMetrics(metrics)
+ reportHostMetrics(metrics)
+ reportServerMetrics(metrics)
CompletableResultCode.ofSuccess()
} catch (e: Throwable) {
CompletableResultCode.ofFailure()
}
}
- private var lastHostMetrics: Map<String, HBuffer> = emptyMap()
- private val hostMetricsSingleton = HBuffer()
+ override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess()
+
+ override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess()
+
+ private fun reportServiceMetrics(metrics: Collection<MetricData>) {
+ monitor.record(extractServiceMetrics(clock.millis(), metrics))
+ }
+
+ private val hosts = mutableMapOf<String, HostAggregator>()
+ private val servers = mutableMapOf<String, ServerAggregator>()
private fun reportHostMetrics(metrics: Collection<MetricData>) {
- val hostMetrics = mutableMapOf<String, HBuffer>()
+ val hosts = hosts
+ val servers = servers
+
+ for (metric in metrics) {
+ val resource = metric.resource
+ val hostId = resource.attributes[HOST_ID] ?: continue
+ val agg = hosts.computeIfAbsent(hostId) { HostAggregator(resource) }
+ agg.accept(metric)
+ }
+
+ val monitor = monitor
+ val now = clock.millis()
+ for ((_, server) in servers) {
+ server.record(monitor, now)
+ }
+ }
+
+ private fun reportServerMetrics(metrics: Collection<MetricData>) {
+ val hosts = hosts
for (metric in metrics) {
+ val resource = metric.resource
+ val host = resource.attributes[HOST_ID]?.let { hosts[it]?.host }
+
when (metric.name) {
- "cpu.demand" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuDemand = v }
- "cpu.usage" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuUsage = v }
- "power.usage" -> mapDoubleHistogram(metric, hostMetrics) { m, v -> m.powerDraw = v }
- "cpu.work.total" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.totalWork = v }
- "cpu.work.granted" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.grantedWork = v }
- "cpu.work.overcommit" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.overcommittedWork = v }
- "cpu.work.interference" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.interferedWork = v }
- "guests.active" -> mapLongSum(metric, hostMetrics) { m, v -> m.instanceCount = v.toInt() }
- "host.time.up" -> mapLongSum(metric, hostMetrics) { m, v -> m.uptime = v }
- "host.time.down" -> mapLongSum(metric, hostMetrics) { m, v -> m.downtime = v }
+ "scheduler.duration" -> mapByServer(metric.doubleHistogramData.points, host) { agg, point ->
+ agg.schedulingLatency = point.sum / point.count
+ }
+ "guest.time.running" -> mapByServer(metric.longSumData.points, host) { agg, point ->
+ agg.uptime = point.value
+ }
+ "guest.time.error" -> mapByServer(metric.longSumData.points, host) { agg, point ->
+ agg.downtime = point.value
+ }
}
}
- for ((id, hostMetric) in hostMetrics) {
- val lastHostMetric = lastHostMetrics.getOrDefault(id, hostMetricsSingleton)
- val host = hosts[id] ?: continue
+ val monitor = monitor
+ val now = clock.millis()
+ for ((_, host) in hosts) {
+ host.record(monitor, now)
+ }
+ }
+
+ /**
+ * Helper function to map a metric by the server.
+ */
+ private inline fun <P : PointData> mapByServer(points: Collection<P>, host: HostInfo? = null, block: (ServerAggregator, P) -> Unit) {
+ for (point in points) {
+ val serverId = point.attributes[ResourceAttributes.HOST_ID] ?: continue
+ val agg = servers.computeIfAbsent(serverId) { ServerAggregator(point.attributes) }
+
+ if (host != null) {
+ agg.host = host
+ }
+
+ block(agg, point)
+ }
+ }
+
+ /**
+ * An aggregator for host metrics before they are reported.
+ */
+ private class HostAggregator(resource: Resource) {
+ /**
+ * The static information about this host.
+ */
+ val host = HostInfo(
+ resource.attributes[HOST_ID]!!,
+ resource.attributes[HOST_NAME]!!,
+ resource.attributes[HOST_ARCH]!!,
+ resource.attributes[HOST_NCPUS]!!.toInt(),
+ resource.attributes[HOST_MEM_CAPACITY]!!,
+ )
+
+ private var totalWork: Double = 0.0
+ private var previousTotalWork = 0.0
+ private var grantedWork: Double = 0.0
+ private var previousGrantedWork = 0.0
+ private var overcommittedWork: Double = 0.0
+ private var previousOvercommittedWork = 0.0
+ private var interferedWork: Double = 0.0
+ private var previousInterferedWork = 0.0
+ private var cpuUsage: Double = 0.0
+ private var cpuDemand: Double = 0.0
+ private var instanceCount: Int = 0
+ private var powerDraw: Double = 0.0
+ private var uptime: Long = 0
+ private var previousUptime = 0L
+ private var downtime: Long = 0
+ private var previousDowntime = 0L
+ fun record(monitor: ComputeMonitor, now: Long) {
monitor.record(
HostData(
- clock.millis(),
+ now,
host,
- hostMetric.totalWork - lastHostMetric.totalWork,
- hostMetric.grantedWork - lastHostMetric.grantedWork,
- hostMetric.overcommittedWork - lastHostMetric.overcommittedWork,
- hostMetric.interferedWork - lastHostMetric.interferedWork,
- hostMetric.cpuUsage,
- hostMetric.cpuDemand,
- hostMetric.instanceCount,
- hostMetric.powerDraw,
- hostMetric.uptime - lastHostMetric.uptime,
- hostMetric.downtime - lastHostMetric.downtime,
+ totalWork - previousTotalWork,
+ grantedWork - previousGrantedWork,
+ overcommittedWork - previousOvercommittedWork,
+ interferedWork - previousInterferedWork,
+ cpuUsage,
+ cpuDemand,
+ instanceCount,
+ powerDraw,
+ uptime - previousUptime,
+ downtime - previousDowntime,
)
)
- }
-
- lastHostMetrics = hostMetrics
- }
- private fun mapDoubleSummary(data: MetricData, hostMetrics: MutableMap<String, HBuffer>, block: (HBuffer, Double) -> Unit) {
- val points = data.doubleSummaryData?.points ?: emptyList()
- for (point in points) {
- val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue
- val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() }
- val avg = (point.percentileValues[0].value + point.percentileValues[1].value) / 2
- block(hostMetric, avg)
+ previousTotalWork = totalWork
+ previousGrantedWork = grantedWork
+ previousOvercommittedWork = overcommittedWork
+ previousInterferedWork = interferedWork
+ previousUptime = uptime
+ previousDowntime = downtime
+ reset()
}
- }
- private fun mapDoubleHistogram(data: MetricData, hostMetrics: MutableMap<String, HBuffer>, block: (HBuffer, Double) -> Unit) {
- val points = data.doubleHistogramData?.points ?: emptyList()
- for (point in points) {
- val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue
- val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() }
- block(hostMetric, point.sum / point.count)
+ /**
+ * Accept the [MetricData] for this host.
+ */
+ fun accept(data: MetricData) {
+ when (data.name) {
+ "cpu.work.total" -> totalWork = data.doubleSumData.points.first().value
+ "cpu.work.granted" -> grantedWork = data.doubleSumData.points.first().value
+ "cpu.work.overcommit" -> overcommittedWork = data.doubleSumData.points.first().value
+ "cpu.work.interference" -> interferedWork = data.doubleSumData.points.first().value
+ "power.usage" -> powerDraw = acceptHistogram(data)
+ "cpu.usage" -> cpuUsage = acceptHistogram(data)
+ "cpu.demand" -> cpuDemand = acceptHistogram(data)
+ "guests.active" -> instanceCount = data.longSumData.points.first().value.toInt()
+ "host.time.up" -> uptime = data.longSumData.points.first().value
+ "host.time.down" -> downtime = data.longSumData.points.first().value
+ }
}
- }
- private fun mapLongSum(data: MetricData?, hostMetrics: MutableMap<String, HBuffer>, block: (HBuffer, Long) -> Unit) {
- val points = data?.longSumData?.points ?: emptyList()
- for (point in points) {
- val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue
- val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() }
- block(hostMetric, point.value)
+ private fun acceptHistogram(data: MetricData): Double {
+ return when (data.type) {
+ MetricDataType.HISTOGRAM -> {
+ val point = data.doubleHistogramData.points.first()
+ point.sum / point.count
+ }
+ MetricDataType.SUMMARY -> {
+ val point = data.doubleSummaryData.points.first()
+ point.sum / point.count
+ }
+ else -> error("Invalid metric type")
+ }
}
- }
- private fun mapDoubleSum(data: MetricData?, hostMetrics: MutableMap<String, HBuffer>, block: (HBuffer, Double) -> Unit) {
- val points = data?.doubleSumData?.points ?: emptyList()
- for (point in points) {
- val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue
- val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() }
- block(hostMetric, point.value)
+ private fun reset() {
+ totalWork = 0.0
+ grantedWork = 0.0
+ overcommittedWork = 0.0
+ interferedWork = 0.0
+ cpuUsage = 0.0
+ cpuDemand = 0.0
+ instanceCount = 0
+ powerDraw = 0.0
+ uptime = 0L
+ downtime = 0L
}
}
/**
- * A buffer for host metrics before they are reported.
+ * An aggregator for server metrics before they are reported.
*/
- private class HBuffer {
- var totalWork: Double = 0.0
- var grantedWork: Double = 0.0
- var overcommittedWork: Double = 0.0
- var interferedWork: Double = 0.0
- var cpuUsage: Double = 0.0
- var cpuDemand: Double = 0.0
- var instanceCount: Int = 0
- var powerDraw: Double = 0.0
- var uptime: Long = 0
- var downtime: Long = 0
- }
+ private class ServerAggregator(attributes: Attributes) {
+ /**
+ * The static information about this server.
+ */
+ val server = ServerInfo(
+ attributes[ResourceAttributes.HOST_ID]!!,
+ attributes[ResourceAttributes.HOST_NAME]!!,
+ attributes[ResourceAttributes.HOST_TYPE]!!,
+ attributes[ResourceAttributes.HOST_ARCH]!!,
+ attributes[ResourceAttributes.HOST_IMAGE_ID]!!,
+ attributes[ResourceAttributes.HOST_IMAGE_NAME]!!,
+ attributes[AttributeKey.longKey("host.num_cpus")]!!.toInt(),
+ attributes[AttributeKey.longKey("host.mem_capacity")]!!,
+ )
- private fun reportServiceMetrics(metrics: Collection<MetricData>) {
- monitor.record(extractServiceMetrics(clock.millis(), metrics))
- }
+ /**
+ * The [HostInfo] of the host on which the server is hosted.
+ */
+ var host: HostInfo? = null
- override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess()
+ @JvmField var uptime: Long = 0
+ private var previousUptime = 0L
+ @JvmField var downtime: Long = 0
+ private var previousDowntime = 0L
+ @JvmField var schedulingLatency = 0.0
- override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess()
+ fun record(monitor: ComputeMonitor, now: Long) {
+ monitor.record(
+ ServerData(
+ now,
+ server,
+ null,
+ uptime - previousUptime,
+ downtime - previousDowntime,
+ )
+ )
+
+ previousUptime = uptime
+ previousDowntime = downtime
+ reset()
+ }
+
+ private fun reset() {
+ host = null
+ uptime = 0L
+ downtime = 0L
+ }
+ }
}
diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt
index ec303b37..d51bcab4 100644
--- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt
+++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt
@@ -22,10 +22,6 @@
package org.opendc.telemetry.compute
-import org.opendc.compute.api.Server
-import org.opendc.compute.api.ServerState
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.driver.HostState
import org.opendc.telemetry.compute.table.HostData
import org.opendc.telemetry.compute.table.ServerData
import org.opendc.telemetry.compute.table.ServiceData
@@ -35,16 +31,6 @@ import org.opendc.telemetry.compute.table.ServiceData
*/
public interface ComputeMonitor {
/**
- * This method is invoked when the state of a [Server] changes.
- */
- public fun onStateChange(timestamp: Long, server: Server, newState: ServerState) {}
-
- /**
- * This method is invoked when the state of a [Host] changes.
- */
- public fun onStateChange(time: Long, host: Host, newState: HostState) {}
-
- /**
* Record the specified [data].
*/
public fun record(data: ServerData) {}
diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt
index 01df0e69..1f309f1b 100644
--- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt
+++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt
@@ -24,51 +24,7 @@ package org.opendc.telemetry.compute
import io.opentelemetry.sdk.metrics.data.MetricData
import io.opentelemetry.sdk.metrics.export.MetricProducer
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.coroutineScope
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.driver.HostListener
-import org.opendc.compute.service.driver.HostState
import org.opendc.telemetry.compute.table.ServiceData
-import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader
-import java.time.Clock
-import java.time.Duration
-
-/**
- * Attach the specified monitor to the OpenDC Compute service.
- */
-public suspend fun withMonitor(
- scheduler: ComputeService,
- clock: Clock,
- metricProducer: MetricProducer,
- monitor: ComputeMonitor,
- exportInterval: Duration = Duration.ofMinutes(5), /* Every 5 min (which is the granularity of the workload trace) */
- block: suspend CoroutineScope.() -> Unit
-): Unit = coroutineScope {
- // Monitor host events
- for (host in scheduler.hosts) {
- monitor.onStateChange(clock.millis(), host, HostState.UP)
- host.addListener(object : HostListener {
- override fun onStateChanged(host: Host, newState: HostState) {
- monitor.onStateChange(clock.millis(), host, newState)
- }
- })
- }
-
- val reader = CoroutineMetricReader(
- this,
- listOf(metricProducer),
- ComputeMetricExporter(clock, scheduler.hosts.associateBy { it.uid.toString() }, monitor),
- exportInterval
- )
-
- try {
- block(this)
- } finally {
- reader.close()
- }
-}
/**
* Collect the metrics of the compute service.
diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/HostAttributes.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/HostAttributes.kt
new file mode 100644
index 00000000..7dca6186
--- /dev/null
+++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/HostAttributes.kt
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+@file:JvmName("HostAttributes")
+package org.opendc.telemetry.compute
+
+import io.opentelemetry.api.common.AttributeKey
+
+/**
+ * The identifier of the node hosting virtual machines.
+ */
+public val HOST_ID: AttributeKey<String> = AttributeKey.stringKey("node.id")
+
+/**
+ * The name of the node hosting virtual machines.
+ */
+public val HOST_NAME: AttributeKey<String> = AttributeKey.stringKey("node.name")
+
+/**
+ * The CPU architecture of the host node.
+ */
+public val HOST_ARCH: AttributeKey<String> = AttributeKey.stringKey("node.arch")
+
+/**
+ * The number of CPUs in the host node.
+ */
+public val HOST_NCPUS: AttributeKey<Long> = AttributeKey.longKey("node.num_cpus")
+
+/**
+ * The amount of memory installed in the host node in MiB.
+ */
+public val HOST_MEM_CAPACITY: AttributeKey<Long> = AttributeKey.longKey("node.mem_capacity")
diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt
index 8e6c34d0..e3ecda3d 100644
--- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt
+++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt
@@ -22,14 +22,12 @@
package org.opendc.telemetry.compute.table
-import org.opendc.compute.service.driver.Host
-
/**
* A trace entry for a particular host.
*/
public data class HostData(
public val timestamp: Long,
- public val host: Host,
+ public val host: HostInfo,
public val totalWork: Double,
public val grantedWork: Double,
public val overcommittedWork: Double,
diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostInfo.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostInfo.kt
new file mode 100644
index 00000000..d9a5906b
--- /dev/null
+++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostInfo.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.telemetry.compute.table
+
+/**
+ * Information about a host exposed to the telemetry service.
+ */
+public data class HostInfo(val id: String, val name: String, val arch: String, val cpuCount: Int, val memCapacity: Long)
diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt
index 2a9fa8a6..7fde86d9 100644
--- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt
+++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt
@@ -22,14 +22,13 @@
package org.opendc.telemetry.compute.table
-import org.opendc.compute.api.Server
-
/**
* A trace entry for a particular server.
*/
public data class ServerData(
public val timestamp: Long,
- public val server: Server,
+ public val server: ServerInfo,
+ public val host: HostInfo?,
public val uptime: Long,
public val downtime: Long,
)
diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerInfo.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerInfo.kt
new file mode 100644
index 00000000..b16e5f3d
--- /dev/null
+++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerInfo.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.telemetry.compute.table
+
+/**
+ * Static information about a server exposed to the telemetry service.
+ */
+public data class ServerInfo(
+ val id: String,
+ val name: String,
+ val type: String,
+ val arch: String,
+ val imageId: String,
+ val imageName: String,
+ val cpuCount: Int,
+ val memCapacity: Long
+)