64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type infraStatusResponse struct {
|
|
At time.Time `json:"at"`
|
|
Sidecar map[string]any `json:"sidecar,omitempty"`
|
|
SidecarError string `json:"sidecar_error,omitempty"`
|
|
}
|
|
|
|
func (s *Server) handleInfraStatus(w http.ResponseWriter, r *http.Request) {
|
|
resp := infraStatusResponse{At: time.Now().UTC()}
|
|
baseURL := strings.TrimRight(strings.TrimSpace(s.cfg.AIStatsSidecarURL), "/")
|
|
if baseURL == "" {
|
|
resp.SidecarError = "AI stats sidecar is not configured"
|
|
writeJSON(w, http.StatusOK, resp)
|
|
return
|
|
}
|
|
|
|
timeout := s.cfg.AIStatsTimeout
|
|
if timeout <= 0 {
|
|
timeout = 8 * time.Second
|
|
}
|
|
ctx, cancel := contextWithTimeout(r, timeout)
|
|
defer cancel()
|
|
sidecar, err := fetchAIStatsSidecar(ctx, baseURL, timeout)
|
|
if err != nil {
|
|
resp.SidecarError = err.Error()
|
|
} else {
|
|
resp.Sidecar = sidecar
|
|
}
|
|
writeJSON(w, http.StatusOK, resp)
|
|
}
|
|
|
|
func fetchAIStatsSidecar(ctx context.Context, baseURL string, timeout time.Duration) (map[string]any, error) {
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, baseURL+"/stats", nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
client := &http.Client{Timeout: timeout}
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer res.Body.Close()
|
|
if res.StatusCode >= 300 {
|
|
body, _ := io.ReadAll(io.LimitReader(res.Body, 2048))
|
|
return nil, fmt.Errorf("sidecar HTTP %d: %s", res.StatusCode, strings.TrimSpace(string(body)))
|
|
}
|
|
var out map[string]any
|
|
if err := json.NewDecoder(res.Body).Decode(&out); err != nil {
|
|
return nil, err
|
|
}
|
|
return out, nil
|
|
}
|