feat: add bounded process metrics and private monitoring endpoint

This commit is contained in:
2026-09-18 13:17:33 +08:00
parent 1f1d833f69
commit a7be32f661
24 changed files with 1467 additions and 19 deletions

View File

@@ -0,0 +1,64 @@
package observability
import (
"context"
"database/sql"
"errors"
"runtime"
"time"
)
// initializeProcess is called once by the registry constructor.
func (r *Registry) initializeProcess() {
if r == nil {
return
}
r.SetGauge("orbit_process_start_time_seconds", float64(r.started.Unix()), nil)
r.SetGauge("orbit_build_info", 1, Labels{"go_version": runtime.Version()})
r.RecordProcess()
for _, component := range components {
labels := Labels{"component": component}
r.SetGauge("orbit_runtime_batch_last_success_timestamp_seconds", 0, labels)
for _, outcome := range []string{"success", "error", "cancelled"} {
r.AddCounter("orbit_runtime_batch_total", 0, Labels{"component": component, "outcome": outcome})
}
}
for _, route := range []string{"worker_connect", "event_connect"} {
r.SetGauge("orbit_websocket_connections", 0, Labels{"route": route})
r.AddCounter("orbit_websocket_connections_total", 0, Labels{"route": route})
}
}
func (r *Registry) RecordProcess() {
if r == nil {
return
}
r.SetGauge("orbit_process_uptime_seconds", time.Since(r.started).Seconds(), nil)
r.SetGauge("orbit_go_goroutines", float64(runtime.NumGoroutine()), nil)
}
func (r *Registry) RecordBatch(component string, started time.Time, err error) {
if r == nil {
return
}
outcome := "success"
if err != nil {
outcome = "error"
if errors.Is(err, context.Canceled) {
outcome = "cancelled"
}
}
r.AddCounter("orbit_runtime_batch_total", 1, Labels{"component": component, "outcome": outcome})
r.ObserveHistogram("orbit_runtime_batch_duration_seconds", time.Since(started).Seconds(), Labels{"component": component})
if err == nil {
r.SetGauge("orbit_runtime_batch_last_success_timestamp_seconds", float64(time.Now().Unix()), Labels{"component": component})
}
}
// RecordDatabase reads the local connection-pool snapshot; it issues no SQL.
func (r *Registry) RecordDatabase(s sql.DBStats) {
r.SetGauge("orbit_db_connections_open", float64(s.OpenConnections), nil)
r.SetGauge("orbit_db_connections_in_use", float64(s.InUse), nil)
r.SetGauge("orbit_db_connections_idle", float64(s.Idle), nil)
r.SetGauge("orbit_db_connections_max_open", float64(s.MaxOpenConnections), nil)
r.SetCounter("orbit_db_wait_count_total", float64(s.WaitCount), nil)
r.SetCounter("orbit_db_wait_duration_seconds_total", s.WaitDuration.Seconds(), nil)
}