Files
ai-service/internal/httpapi/infra.go
Grendgi c9435612ec
All checks were successful
CI / test (push) Successful in 16s
Build and Deploy / build-and-deploy (push) Successful in 23s
Expose AI infrastructure status
2026-06-08 16:35:08 +03:00

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
}