Files
Grendgi 3ecdcd395e
All checks were successful
CI / test (push) Successful in 16s
Build and Deploy / build-and-deploy (push) Successful in 22s
Add AI service dashboard endpoint
2026-06-08 17:23:01 +03:00

69 lines
1.7 KiB
Go

package httpapi
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"time"
"ai-service/internal/config"
)
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) {
writeJSON(w, http.StatusOK, loadInfraSnapshot(r, s.cfg))
}
func loadInfraSnapshot(r *http.Request, cfg config.Config) infraStatusResponse {
resp := infraStatusResponse{At: time.Now().UTC()}
baseURL := strings.TrimRight(strings.TrimSpace(cfg.AIStatsSidecarURL), "/")
if baseURL == "" {
resp.SidecarError = "AI stats sidecar is not configured"
return resp
}
timeout := 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
}
return 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
}