Skip to content

Commit 63693d6

Browse files
author
Andrea Falzetti
committed
feat(jetbrains): show workspace resources
1 parent 6f8ed36 commit 63693d6

File tree

4 files changed

+165
-0
lines changed

4 files changed

+165
-0
lines changed

components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodManager.kt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,4 +365,31 @@ class GitpodManager : Disposable {
365365
}
366366
}
367367
}
368+
369+
var resourceStatus: Status.ResourcesStatusResponse? = null
370+
371+
private val metricsJob = GlobalScope.launch {
372+
if (application.isHeadlessEnvironment) {
373+
return@launch
374+
}
375+
val status = StatusServiceGrpc.newFutureStub(supervisorChannel)
376+
while (isActive) {
377+
try {
378+
val f = status.resourcesStatus(Status.ResourcesStatuRequest.getDefaultInstance())
379+
resourceStatus = f.asDeferred().await()
380+
} catch (t: Throwable) {
381+
if (t is CancellationException) {
382+
throw t
383+
}
384+
thisLogger().error("gitpod: failed to retrieve resource status: ", t)
385+
}
386+
delay(1000L)
387+
}
388+
}
389+
init {
390+
lifetime.onTerminationOrNow {
391+
metricsJob.cancel()
392+
}
393+
}
394+
368395
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License-AGPL.txt in the project root for license information.
4+
5+
package io.gitpod.jetbrains.remote.latest
6+
7+
import com.jetbrains.ide.model.uiautomation.BeControl
8+
import com.jetbrains.rd.ui.bedsl.dsl.VerticalGridBuilder
9+
import com.jetbrains.rd.ui.bedsl.dsl.verticalGrid
10+
import com.jetbrains.rd.util.lifetime.Lifetime
11+
import com.jetbrains.rd.util.reactive.Property
12+
import com.jetbrains.rdserver.diagnostics.BackendDiagnosticsService
13+
import com.jetbrains.rdserver.unattendedHost.customization.controlCenter.performance.MetricControlProvider
14+
import com.jetbrains.rdserver.unattendedHost.customization.controlCenter.performance.createProgressBar
15+
import com.jetbrains.rdserver.unattendedHost.customization.controlCenter.performance.createProgressRow
16+
17+
class GitpodMetricControlProvider : MetricControlProvider {
18+
override val id: String = "gitpodMetricsControl"
19+
override fun getControl(lifetime: Lifetime): BeControl {
20+
return verticalGrid {
21+
val backendDiagnosticsService = BackendDiagnosticsService.Companion.getInstance()
22+
createCpuControl(this, backendDiagnosticsService, lifetime)
23+
createMemoryControl(this, backendDiagnosticsService, lifetime)
24+
}
25+
}
26+
27+
private fun createCpuControl(ctx: VerticalGridBuilder, backendDiagnosticsService: BackendDiagnosticsService, lifetime: Lifetime) {
28+
val cpuUsed = backendDiagnosticsService.getMetric("gitpod_workspace_cpu_used")
29+
val cpuTotal = backendDiagnosticsService.getMetric("gitpod_workspace_cpu_total")
30+
val cpuPercentage = backendDiagnosticsService.getMetric("gitpod_workspace_cpu_percentage")
31+
val cpuPercentageProperty = Property("$cpuPercentage %")
32+
val label = "Workspace CPU"
33+
val progressBar = createProgressBar(lifetime, cpuPercentage.valueProperty, cpuPercentageProperty)
34+
val labelProperty = Property("")
35+
36+
fun updateLabel() {
37+
labelProperty.set("${cpuUsed}m / ${cpuTotal}m")
38+
}
39+
updateLabel()
40+
cpuUsed.valueProperty.change.advise(lifetime) {
41+
updateLabel()
42+
}
43+
cpuTotal.valueProperty.change.advise(lifetime) {
44+
updateLabel()
45+
}
46+
createProgressRow(ctx, lifetime, label, cpuPercentage.statusProperty, labelProperty, cpuPercentageProperty, progressBar)
47+
}
48+
49+
private fun createMemoryControl(ctx: VerticalGridBuilder, backendDiagnosticsService: BackendDiagnosticsService, lifetime: Lifetime) {
50+
val memoryUsed = backendDiagnosticsService.getMetric("gitpod_workspace_memory_used")
51+
val memoryTotal = backendDiagnosticsService.getMetric("gitpod_workspace_memory_total")
52+
val memoryPercentage = backendDiagnosticsService.getMetric("gitpod_workspace_memory_percentage")
53+
val memoryPercentageProperty = Property("$memoryPercentage %")
54+
val label = "Workspace Memory"
55+
val progressBar = createProgressBar(lifetime, memoryPercentage.valueProperty, memoryPercentageProperty)
56+
val labelProperty = Property("")
57+
58+
fun updateLabel() {
59+
labelProperty.set("${memoryUsed}GB / ${memoryTotal}GB")
60+
}
61+
updateLabel()
62+
memoryUsed.valueProperty.change.advise(lifetime) {
63+
updateLabel()
64+
}
65+
memoryTotal.valueProperty.change.advise(lifetime) {
66+
updateLabel()
67+
}
68+
69+
createProgressRow(ctx, lifetime, label, memoryPercentage.statusProperty, labelProperty, memoryPercentageProperty, progressBar)
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License-AGPL.txt in the project root for license information.
4+
5+
package io.gitpod.jetbrains.remote.latest
6+
7+
import com.intellij.openapi.components.service
8+
import com.jetbrains.rd.platform.codeWithMe.unattendedHost.metrics.Metric
9+
import com.jetbrains.rd.platform.codeWithMe.unattendedHost.metrics.MetricType
10+
import com.jetbrains.rd.platform.codeWithMe.unattendedHost.metrics.MetricsStatus
11+
import com.jetbrains.rd.platform.codeWithMe.unattendedHost.metrics.providers.MetricProvider
12+
import io.gitpod.jetbrains.remote.GitpodManager
13+
import kotlin.math.roundToInt
14+
15+
class GitpodMetricProvider: MetricProvider {
16+
private val manager = service<GitpodManager>()
17+
18+
override val id: String = "gitpodMetricsProvider"
19+
override fun getMetrics(): Map<String, Metric> {
20+
val resourceStatus = manager.resourceStatus
21+
22+
val cpuUsed = resourceStatus?.cpu?.used?.toDouble() ?: 0.0
23+
val cpuTotal = resourceStatus?.cpu?.limit?.toDouble() ?: 0.0
24+
val cpuPercentage = (cpuUsed / cpuTotal) * 100
25+
26+
// TODO: retrieve thresholds from supervisor once we implement this: https://github.com/gitpod-io/gitpod/issues/12075
27+
val cpuStatus = if (cpuPercentage >= 95) {
28+
MetricsStatus.DANGER
29+
} else if (cpuPercentage >= 80) {
30+
MetricsStatus.WARNING
31+
} else {
32+
MetricsStatus.NORMAL
33+
}
34+
35+
val memoryUsed = convertBytesToGB(resourceStatus?.memory?.used ?: 0)
36+
val memoryTotal = convertBytesToGB(resourceStatus?.memory?.limit ?: 0)
37+
val memoryPercentage = (memoryUsed / memoryTotal) * 100
38+
39+
// TODO: retrieve thresholds from supervisor once we implement this: https://github.com/gitpod-io/gitpod/issues/12075
40+
val memoryStatus = if (memoryPercentage >= 95) {
41+
MetricsStatus.DANGER
42+
} else if (memoryPercentage >= 80) {
43+
MetricsStatus.WARNING
44+
} else {
45+
MetricsStatus.NORMAL
46+
}
47+
48+
return mapOf(
49+
"gitpod_workspace_cpu_used" to Metric(MetricType.PERFORMANCE, MetricsStatus.NORMAL, roundTo(cpuUsed, 0)),
50+
"gitpod_workspace_cpu_total" to Metric(MetricType.PERFORMANCE, MetricsStatus.NORMAL, roundTo(cpuTotal, 0)),
51+
"gitpod_workspace_cpu_percentage" to Metric(MetricType.PERFORMANCE, cpuStatus, (cpuPercentage * 1000.0).roundToInt() / 1000.0),
52+
"gitpod_workspace_memory_used" to Metric(MetricType.PERFORMANCE, MetricsStatus.NORMAL, roundTo(memoryUsed, 2)),
53+
"gitpod_workspace_memory_total" to Metric(MetricType.PERFORMANCE, MetricsStatus.NORMAL, roundTo(memoryTotal, 2)),
54+
"gitpod_workspace_memory_percentage" to Metric(MetricType.PERFORMANCE, memoryStatus, (memoryPercentage * 1000.0).roundToInt() / 1000.0)
55+
)
56+
}
57+
58+
private fun convertBytesToGB(bytes: Long) : Double {
59+
return bytes.div(1073741824.0)
60+
}
61+
62+
private fun roundTo(number: Double, decimals: Int) : String {
63+
return String.format("%.${decimals}f", number)
64+
}
65+
}

components/ide/jetbrains/backend-plugin/src/main/resources-latest/META-INF/extensions.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,7 @@
77
<extensions defaultExtensionNs="com.intellij">
88
<projectService serviceImplementation="io.gitpod.jetbrains.remote.latest.GitpodTerminalService" client="guest" preload="true"/>
99
<projectService serviceImplementation="io.gitpod.jetbrains.remote.latest.GitpodPortForwardingService" preload="true"/>
10+
<gateway.customization.performance id="gitpodMetricsControl" order="before cpuControl" implementation="io.gitpod.jetbrains.remote.latest.GitpodMetricControlProvider"/>
11+
<gateway.customization.metrics id="gitpodMetricsProvider" implementation="io.gitpod.jetbrains.remote.latest.GitpodMetricProvider" />
1012
</extensions>
1113
</idea-plugin>

0 commit comments

Comments
 (0)