@@ -19,7 +19,6 @@ import git4idea.config.GitVcsApplicationSettings
19
19
import io.gitpod.gitpodprotocol.api.GitpodClient
20
20
import io.gitpod.gitpodprotocol.api.GitpodServerLauncher
21
21
import io.gitpod.jetbrains.remote.services.HeartbeatService
22
- import io.gitpod.jetbrains.remote.utils.LatencyRecord
23
22
import io.gitpod.jetbrains.remote.utils.Retrier.retry
24
23
import io.gitpod.supervisor.api.*
25
24
import io.gitpod.supervisor.api.Info.WorkspaceInfoResponse
@@ -28,6 +27,9 @@ import io.grpc.ManagedChannel
28
27
import io.grpc.ManagedChannelBuilder
29
28
import io.grpc.stub.ClientCallStreamObserver
30
29
import io.grpc.stub.ClientResponseObserver
30
+ import io.prometheus.client.CollectorRegistry
31
+ import io.prometheus.client.Gauge
32
+ import io.prometheus.client.exporter.PushGateway
31
33
import kotlinx.coroutines.GlobalScope
32
34
import kotlinx.coroutines.delay
33
35
import kotlinx.coroutines.future.await
@@ -39,8 +41,6 @@ import java.net.URI
39
41
import java.net.http.HttpClient
40
42
import java.net.http.HttpRequest
41
43
import java.net.http.HttpResponse
42
- import java.nio.file.Files
43
- import java.nio.file.Paths
44
44
import java.time.Duration
45
45
import java.util.concurrent.CancellationException
46
46
import java.util.concurrent.CompletableFuture
@@ -56,40 +56,45 @@ class GitpodManager : Disposable {
56
56
}
57
57
58
58
val devMode = System .getenv(" JB_DEV" ).toBoolean()
59
+ private val backendKind = System .getenv(" JETBRAINS_GITPOD_BACKEND_KIND" ) ? : " unknown"
59
60
60
61
private val lifetime = Lifetime .Eternal .createNested()
61
62
62
63
override fun dispose () {
63
64
lifetime.terminate()
64
65
}
65
66
66
- private val memProfileMode = System .getenv(" JB_MEM_PROFILE" ).toBoolean()
67
-
68
67
init {
69
- val memProfileJob = GlobalScope .launch {
70
- if (application.isHeadlessEnvironment || ! memProfileMode ) {
68
+ val monitoringJob = GlobalScope .launch {
69
+ if (application.isHeadlessEnvironment) {
71
70
return @launch
72
71
}
73
- Files .newBufferedWriter(Paths .get(" /tmp/jb_mem_profile.log" )).use { writer ->
74
- writer.write(" " )
75
- writer.flush()
76
- val allocatedRecord = LatencyRecord ()
77
- val usedRecord = LatencyRecord ()
78
- while (isActive) {
79
- val totalMemory = Runtime .getRuntime().totalMemory() / (1024 * 1024 )
80
- val usedMemory = (Runtime .getRuntime().totalMemory() - Runtime .getRuntime().freeMemory()) / (1024 * 1024 )
81
- allocatedRecord.update(totalMemory)
82
- usedRecord.update(usedMemory)
83
- writer.write(" allocated - current ${totalMemory} M, avg ${allocatedRecord.averageLatency} M, max ${allocatedRecord.maxLatency} M, 90% percentile ${allocatedRecord.percentile(
84
- 90 )} M\n " )
85
- writer.write(" used - current ${usedMemory} M,avg ${usedRecord.averageLatency} M, max ${usedRecord.maxLatency} M, 90% percentile ${usedRecord.percentile(
86
- 90 )} M\n " )
87
- writer.flush()
88
- delay(1000 )
72
+ val pg = PushGateway (" localhost:22999" )
73
+ val registry = CollectorRegistry ()
74
+ val allocatedGauge = Gauge .build()
75
+ .name(" gitpod_jb_backend_memory_max_bytes" )
76
+ .help(" Total allocated memory of JB backend in bytes." )
77
+ .labelNames(" product" )
78
+ .register(registry)
79
+ val usedGauge = Gauge .build()
80
+ .name(" gitpod_jb_backend_memory_used_bytes" )
81
+ .help(" Used memory of JB backend in bytes." )
82
+ .labelNames(" product" )
83
+ .register(registry)
84
+ while (isActive) {
85
+ val totalMemory = Runtime .getRuntime().totalMemory()
86
+ allocatedGauge.labels(backendKind).set(totalMemory.toDouble())
87
+ val usedMemory = (Runtime .getRuntime().totalMemory() - Runtime .getRuntime().freeMemory())
88
+ usedGauge.labels(backendKind).set(usedMemory.toDouble())
89
+ try {
90
+ pg.push(registry, " jb_backend" )
91
+ } catch (t: Throwable ) {
92
+ thisLogger().error(" gitpod: failed to push monitoring metrics:" , t)
89
93
}
94
+ delay(5000 )
90
95
}
91
96
}
92
- lifetime.onTerminationOrNow { memProfileJob .cancel() }
97
+ lifetime.onTerminationOrNow { monitoringJob .cancel() }
93
98
}
94
99
95
100
init {
0 commit comments