diff --git a/API Server/internal/api/settings.go b/API Server/internal/api/settings.go index ebe7469..fa2e8b1 100644 --- a/API Server/internal/api/settings.go +++ b/API Server/internal/api/settings.go @@ -16,11 +16,11 @@ import ( // URL answers its health check and whether the service-account credentials // authenticate as a superuser. type pbProbe struct { - Reachable bool `json:"reachable"` - HTTPStatus int `json:"httpStatus,omitempty"` - LatencyMs int64 `json:"latencyMs,omitempty"` - Superuser bool `json:"superuser"` - Detail string `json:"detail,omitempty"` + Reachable bool `json:"reachable"` + HTTPStatus int `json:"httpStatus,omitempty"` + LatencyMs *float64 `json:"latencyMs,omitempty"` + Superuser bool `json:"superuser"` + Detail string `json:"detail,omitempty"` } // pbConfigView is the PocketBase-connection shape returned to the panel. The diff --git a/API Server/internal/api/status.go b/API Server/internal/api/status.go index 01b5d49..177b21e 100644 --- a/API Server/internal/api/status.go +++ b/API Server/internal/api/status.go @@ -3,6 +3,7 @@ package api import ( "context" "io" + "math" "net/http" "sync" "time" @@ -11,10 +12,19 @@ import ( // svcHealth is the health of one upstream service, as shown on the panel. type svcHealth struct { Status string `json:"status"` // "ok" | "down" - LatencyMs int64 `json:"latencyMs,omitempty"` HTTPStatus int `json:"httpStatus,omitempty"` URL string `json:"url,omitempty"` - Error string `json:"error,omitempty"` + // Fractional, and a pointer so an absent measurement (this process) stays + // distinguishable from a genuinely fast one: neighbours sharing a Docker + // network answer in well under a millisecond. + LatencyMs *float64 `json:"latencyMs,omitempty"` + Error string `json:"error,omitempty"` +} + +// latencyMs is elapsed time in milliseconds, kept to one decimal. +func latencyMs(d time.Duration) *float64 { + ms := math.Round(float64(d.Microseconds())/100) / 10 + return &ms } // healthClient is a short-timeout client for probing upstreams so a hung @@ -29,7 +39,7 @@ func probe(ctx context.Context, url string) svcHealth { return svcHealth{Status: "down", URL: url, Error: err.Error()} } resp, err := healthClient.Do(req) - lat := time.Since(start).Milliseconds() + lat := latencyMs(time.Since(start)) if err != nil { return svcHealth{Status: "down", URL: url, LatencyMs: lat, Error: err.Error()} }