Feat v0.6.4 admin health/metrics tab + cluster merge
All checks were successful
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-frontend (pull_request) Successful in 5s
CI/CD / test-go-pg (pull_request) Successful in 2m40s
CI/CD / test-sqlite (pull_request) Successful in 2m46s
CI/CD / build-and-deploy (pull_request) Successful in 1m1s
All checks were successful
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-frontend (pull_request) Successful in 5s
CI/CD / test-go-pg (pull_request) Successful in 2m40s
CI/CD / test-sqlite (pull_request) Successful in 2m46s
CI/CD / build-and-deploy (pull_request) Successful in 1m1s
Admin Health tab under Monitoring with auto-refreshing runtime, DB, cluster, and extension metrics panels. New GET /api/v1/admin/metrics endpoint. Fattened heartbeat JSONB with stack, GC CPU%, extension count, sandbox stats, trigger fires. Sandbox runner and trigger engine now track cumulative execution counters. Event bus tracks publish/deliver counts. Health endpoints consolidated via shared builder. Block renderers (mermaid, katex, csv-table, diff-viewer) no longer require chat. cluster-dashboard package retired — merged into admin Health tab. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,26 @@ type Registry struct {
|
||||
startTime time.Time
|
||||
stopCh chan struct{}
|
||||
wg sync.WaitGroup
|
||||
|
||||
// Optional callbacks — set after construction via setters.
|
||||
sandboxStats func() (exec, errors uint64, avgMs float64)
|
||||
triggerFires func() int64
|
||||
extensionCount func() int
|
||||
}
|
||||
|
||||
// SetSandboxStats registers a callback for sandbox execution counters.
|
||||
func (r *Registry) SetSandboxStats(fn func() (uint64, uint64, float64)) {
|
||||
r.sandboxStats = fn
|
||||
}
|
||||
|
||||
// SetTriggerFireCount registers a callback for trigger fire count.
|
||||
func (r *Registry) SetTriggerFireCount(fn func() int64) {
|
||||
r.triggerFires = fn
|
||||
}
|
||||
|
||||
// SetExtensionCount registers a callback for active extension count.
|
||||
func (r *Registry) SetExtensionCount(fn func() int) {
|
||||
r.extensionCount = fn
|
||||
}
|
||||
|
||||
// NewRegistry creates a cluster registry instance.
|
||||
@@ -129,13 +149,28 @@ func (r *Registry) collectStats() json.RawMessage {
|
||||
runtime.ReadMemStats(&m)
|
||||
|
||||
stats := map[string]any{
|
||||
"goroutines": runtime.NumGoroutine(),
|
||||
"heap_alloc": m.HeapAlloc,
|
||||
"heap_sys": m.HeapSys,
|
||||
"gc_cycles": m.NumGC,
|
||||
"gc_pause_ns": m.PauseNs[(m.NumGC+255)%256],
|
||||
"uptime_sec": time.Since(r.startTime).Seconds(),
|
||||
"ws_clients": r.hub.ConnCount(),
|
||||
"goroutines": runtime.NumGoroutine(),
|
||||
"heap_alloc": m.HeapAlloc,
|
||||
"heap_sys": m.HeapSys,
|
||||
"stack_in_use": m.StackInuse,
|
||||
"gc_cycles": m.NumGC,
|
||||
"gc_pause_ns": m.PauseNs[(m.NumGC+255)%256],
|
||||
"gc_cpu_pct": m.GCCPUFraction * 100,
|
||||
"uptime_sec": time.Since(r.startTime).Seconds(),
|
||||
"ws_clients": r.hub.ConnCount(),
|
||||
}
|
||||
|
||||
if r.extensionCount != nil {
|
||||
stats["extensions_loaded"] = r.extensionCount()
|
||||
}
|
||||
if r.sandboxStats != nil {
|
||||
exec, errors, avgMs := r.sandboxStats()
|
||||
stats["starlark_exec_total"] = exec
|
||||
stats["starlark_errors_total"] = errors
|
||||
stats["starlark_avg_duration_ms"] = avgMs
|
||||
}
|
||||
if r.triggerFires != nil {
|
||||
stats["trigger_fires_total"] = r.triggerFires()
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(stats)
|
||||
|
||||
Reference in New Issue
Block a user