diff --git a/internal/metrics/uptime/uptime.go b/internal/metrics/uptime/uptime.go index 9929de5d..825ebff7 100644 --- a/internal/metrics/uptime/uptime.go +++ b/internal/metrics/uptime/uptime.go @@ -18,8 +18,8 @@ import ( type ( StatusByAlias struct { - Map map[string]routes.HealthInfo `json:"statuses"` - Timestamp int64 `json:"timestamp"` + Map map[string]*routes.HealthInfo `json:"statuses"` + Timestamp int64 `json:"timestamp"` } // @name RouteStatusesByAlias Status struct { Status types.HealthStatus `json:"status" swaggertype:"string" enums:"healthy,unhealthy,unknown,napping,starting"` diff --git a/internal/route/routes/query.go b/internal/route/routes/query.go index 4ba82dae..c0e7e834 100644 --- a/internal/route/routes/query.go +++ b/internal/route/routes/query.go @@ -54,23 +54,23 @@ func (info *HealthInfo) UnmarshalJSON(data []byte) error { return nil } -func GetHealthInfo() map[string]HealthInfo { - healthMap := make(map[string]HealthInfo, NumRoutes()) +func GetHealthInfo() map[string]*HealthInfo { + healthMap := make(map[string]*HealthInfo, NumRoutes()) for r := range Iter { healthMap[r.Name()] = getHealthInfo(r) } return healthMap } -func getHealthInfo(r types.Route) HealthInfo { +func getHealthInfo(r types.Route) *HealthInfo { mon := r.HealthMonitor() if mon == nil { - return HealthInfo{ + return &HealthInfo{ Status: types.StatusUnknown, Detail: "n/a", } } - return HealthInfo{ + return &HealthInfo{ Status: mon.Status(), Uptime: mon.Uptime(), Latency: mon.Latency(), diff --git a/internal/types/health.go b/internal/types/health.go index 8121ab8f..f6502b67 100644 --- a/internal/types/health.go +++ b/internal/types/health.go @@ -139,6 +139,28 @@ func (s HealthStatus) Idling() bool { return s&IdlingMask != 0 } +func (s HealthStatus) MarshalJSON() ([]byte, error) { + return strconv.AppendQuote(nil, s.String()), nil +} + +func (s *HealthStatus) UnmarshalJSON(data []byte) error { + var v any + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v := v.(type) { + case string: + *s = NewHealthStatusFromString(v) + return nil + case int: + if v > 0 && v < NumStatuses { + *s = HealthStatus(v) + return nil + } + } + return fmt.Errorf("invalid health status type %T of value %v", v, v) +} + func (jsonRepr *HealthJSONRepr) MarshalJSON() ([]byte, error) { var url string if jsonRepr.URL != nil {