mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-08-03 03:39:26 +00:00
fix(go): add eventLoop to /api/health with GC pause percentiles, fixes #147
Go's /api/health was missing the eventLoop object that Node.js provides. The perf.js frontend reads health.eventLoop.p95Ms which crashed with 'Cannot read properties of undefined' when served by the Go server. Adds eventLoop field using GC pause data from runtime.MemStats.PauseNs (last 256 pauses) to compute p50Ms, p95Ms, p99Ms, currentLagMs, maxLagMs — matching the Node.js response shape exactly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -297,6 +297,22 @@ func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// Build eventLoop-equivalent from GC pause data (matches Node.js shape)
|
||||
var gcPauses []float64
|
||||
n := int(m.NumGC)
|
||||
if n > 256 {
|
||||
n = 256
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
idx := (int(m.NumGC) - n + i) % 256
|
||||
gcPauses = append(gcPauses, float64(m.PauseNs[idx])/1e6)
|
||||
}
|
||||
sortedPauses := sortedCopy(gcPauses)
|
||||
var lastPauseMs float64
|
||||
if m.NumGC > 0 {
|
||||
lastPauseMs = float64(m.PauseNs[(m.NumGC+255)%256]) / 1e6
|
||||
}
|
||||
|
||||
writeJSON(w, map[string]interface{}{
|
||||
"status": "ok",
|
||||
"engine": "go",
|
||||
@@ -311,6 +327,13 @@ func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
|
||||
"external": 0,
|
||||
"heapMB": round(float64(m.HeapAlloc)/1048576, 1),
|
||||
},
|
||||
"eventLoop": map[string]interface{}{
|
||||
"currentLagMs": round(lastPauseMs, 1),
|
||||
"maxLagMs": round(percentile(sortedPauses, 1.0), 1),
|
||||
"p50Ms": round(percentile(sortedPauses, 0.5), 1),
|
||||
"p95Ms": round(percentile(sortedPauses, 0.95), 1),
|
||||
"p99Ms": round(percentile(sortedPauses, 0.99), 1),
|
||||
},
|
||||
"goRuntime": map[string]interface{}{
|
||||
"goroutines": runtime.NumGoroutine(),
|
||||
"gcPauses": m.NumGC,
|
||||
|
||||
@@ -81,6 +81,17 @@ func TestHealthEndpoint(t *testing.T) {
|
||||
t.Error("expected estimatedMB in packetStore")
|
||||
}
|
||||
|
||||
// Verify eventLoop (GC pause metrics matching Node.js shape)
|
||||
el, ok := body["eventLoop"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatal("expected eventLoop object in health response")
|
||||
}
|
||||
for _, field := range []string{"currentLagMs", "maxLagMs", "p50Ms", "p95Ms", "p99Ms"} {
|
||||
if _, ok := el[field]; !ok {
|
||||
t.Errorf("expected %s in eventLoop", field)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify cache has real structure
|
||||
cache, ok := body["cache"].(map[string]interface{})
|
||||
if !ok {
|
||||
|
||||
Reference in New Issue
Block a user