Skip to content

Instantly share code, notes, and snippets.

@hikaMaeng
Created February 12, 2025 07:58
Show Gist options
  • Save hikaMaeng/c57a5966e3971b94e4b3b039084daa99 to your computer and use it in GitHub Desktop.
Save hikaMaeng/c57a5966e3971b94e4b3b039084daa99 to your computer and use it in GitHub Desktop.
package server
import com.sun.management.OperatingSystemMXBean
import m42.controller.M42Ctrl
import m42.servicemanager.Context
import org.springframework.http.server.reactive.ServerHttpRequest
import org.springframework.http.server.reactive.ServerHttpResponse
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import java.lang.management.ManagementFactory
private val runtime = Runtime.getRuntime()
private val osBean = ManagementFactory.getOperatingSystemMXBean() as OperatingSystemMXBean
private val threadBean = ManagementFactory.getThreadMXBean()
private var monitoring = false
private val recordedHeapUsage = mutableListOf<Long>()
private val recordedCpuUsage = mutableListOf<Double>()
private val recordedThreads = mutableListOf<Int>()
@RestController
class CtlMatrix(context: Context):M42Ctrl<CtlHello>(context){
override suspend fun hook(httpReq:ServerHttpRequest, httpRes:ServerHttpResponse) {
TODO("Not yet implemented")
}
@GetMapping("/start-metrics")
fun startMetrics(): String {
println("startMetrics-------------------------------------------------------------------")
monitoring = true
recordedHeapUsage.clear()
recordedCpuUsage.clear()
recordedThreads.clear()
return "πŸ“Œ Metrics monitoring started. Server is being observed in real-time."
}
@GetMapping("/end-metrics")
fun endMetrics(): Map<String, Any> {
monitoring = false
println("endMetrics-------------------------------------------------------------------")
return mapOf(
"memory" to calculateStats(recordedHeapUsage, "MB"),
"cpu" to calculateStats(recordedCpuUsage, "%"),
"threads" to calculateStats(recordedThreads, "threads")
)
}
@GetMapping("/current-metrics")
fun currentMetrics(): Map<String, Any> {
return mapOf(
"memory" to getHeapUsed(),
"cpu" to getCpuLoad(),
"threads" to getThreadCount()
)
}
@Scheduled(fixedRate = 100)
fun recordMetrics() {
if (!monitoring) return
recordedHeapUsage.add(getHeapUsed())
recordedCpuUsage.add(getCpuLoad())
recordedThreads.add(getThreadCount())
}
}
private fun calculateStats(data: List<Number>, unit: String): Map<String, Any> {
if (data.isEmpty()) return mapOf("unit" to unit, "error" to "No data recorded")
val l = data.map{it.toDouble()}
val max = l.maxOrNull() ?: 0
val min = l.minOrNull() ?: 0
val avg = l.average()
return mapOf(
"unit" to unit,
"peak" to max,
"low" to min,
"average" to avg
)
}
private fun getHeapUsed(): Long {
return (runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024 // MB
}
private fun getCpuLoad(): Double {
val processCpuLoad = osBean.processCpuLoad // βœ… JVM ν”„λ‘œμ„ΈμŠ€μ— ν•œμ •λœ CPU μ‚¬μš©λ₯ 
return if (processCpuLoad >= 0) processCpuLoad * 100 else 0.0
}
private fun getThreadCount(): Int {
return threadBean.threadCount
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment