From 0452f4eca0173bc38c04800e0cd1ad79cd407beb Mon Sep 17 00:00:00 2001 From: Olivier Cazade Date: Thu, 20 Nov 2025 15:21:28 +0100 Subject: [PATCH 1/3] Add LokiStack operator status integration Integrate with LokiStack operator to use its status conditions instead of querying the Loki status endpoint. This adds support for detecting Loki readiness through the operator's status API when available. Changes: - Add github.com/grafana/loki/operator/apis/loki dependency - Add LokiStackStatus field to Loki config - Check operator status in getLokiStatus before querying status URL - Prevent status URL usage when using Loki operator --- pkg/config/loki.go | 1 + pkg/handler/loki.go | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/pkg/config/loki.go b/pkg/config/loki.go index 54151359b..737829b05 100644 --- a/pkg/config/loki.go +++ b/pkg/config/loki.go @@ -18,6 +18,7 @@ type Loki struct { TokenPath string `yaml:"tokenPath,omitempty" json:"tokenPath,omitempty"` SkipTLS bool `yaml:"skipTls,omitempty" json:"skipTls,omitempty"` CAPath string `yaml:"caPath,omitempty" json:"caPath,omitempty"` + Status string `yaml:"status,omitempty" json:"status,omitempty"` StatusSkipTLS bool `yaml:"statusSkipTls,omitempty" json:"statusSkipTls,omitempty"` StatusCAPath string `yaml:"statusCaPath,omitempty" json:"statusCaPath,omitempty"` StatusUserCertPath string `yaml:"statusUserCertPath,omitempty" json:"statusUserCertPath,omitempty"` diff --git a/pkg/handler/loki.go b/pkg/handler/loki.go index d36adaca7..35bcf55e2 100644 --- a/pkg/handler/loki.go +++ b/pkg/handler/loki.go @@ -198,6 +198,10 @@ func getLokiNamesForPrefix(cfg *config.Loki, lokiClient httpclient.Caller, filts } func (h *Handlers) getLokiStatus(r *http.Request) ([]byte, int, error) { + // Check if the status was provided by the operator + if h.Cfg.Loki.Status != "" { + return []byte(h.Cfg.Loki.Status), 200, nil + } lokiClient := newLokiClient(&h.Cfg.Loki, r.Header, true) baseURL := strings.TrimRight(h.Cfg.Loki.GetStatusURL(), "/") return executeLokiQuery(fmt.Sprintf("%s/%s", baseURL, "ready"), lokiClient) @@ -231,6 +235,10 @@ func (h *Handlers) LokiMetrics() func(w http.ResponseWriter, r *http.Request) { writeError(w, http.StatusBadRequest, "Loki is disabled") return } + if h.Cfg.Loki.Status != nil { + writeError(w, http.StatusBadRequest, "Loki status URL is not usable with Loki operator") + return + } lokiClient := newLokiClient(&h.Cfg.Loki, r.Header, true) baseURL := strings.TrimRight(h.Cfg.Loki.GetStatusURL(), "/") @@ -250,6 +258,10 @@ func (h *Handlers) LokiBuildInfos() func(w http.ResponseWriter, r *http.Request) writeError(w, http.StatusBadRequest, "Loki is disabled") return } + if h.Cfg.Loki.Status != nil { + writeError(w, http.StatusBadRequest, "Loki status URL is not usable with Loki operator") + return + } lokiClient := newLokiClient(&h.Cfg.Loki, r.Header, true) baseURL := strings.TrimRight(h.Cfg.Loki.GetStatusURL(), "/") @@ -264,6 +276,10 @@ func (h *Handlers) LokiBuildInfos() func(w http.ResponseWriter, r *http.Request) } func (h *Handlers) fetchLokiConfig(cl httpclient.Caller, output any) error { + if h.Cfg.Loki.Status != nil { + return fmt.Errorf("loki status url is not usable with Loki operator") + } + baseURL := strings.TrimRight(h.Cfg.Loki.GetStatusURL(), "/") resp, _, err := executeLokiQuery(fmt.Sprintf("%s/%s", baseURL, "config"), cl) From 001adf1887b0de1a663e9c9eca4f64a3520741e9 Mon Sep 17 00:00:00 2001 From: Olivier Cazade Date: Wed, 24 Dec 2025 17:31:23 +0100 Subject: [PATCH 2/3] Update pkg/handler/loki.go Co-authored-by: Mehul Modi --- pkg/handler/loki.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/handler/loki.go b/pkg/handler/loki.go index 35bcf55e2..302a6c8de 100644 --- a/pkg/handler/loki.go +++ b/pkg/handler/loki.go @@ -236,7 +236,7 @@ func (h *Handlers) LokiMetrics() func(w http.ResponseWriter, r *http.Request) { return } if h.Cfg.Loki.Status != nil { - writeError(w, http.StatusBadRequest, "Loki status URL is not usable with Loki operator") + writeError(w, http.StatusBadRequest, "Status URL endpoints are unavailable when using LokiStack operator. Status is provided via operator conditions.") return } lokiClient := newLokiClient(&h.Cfg.Loki, r.Header, true) From d3abf2ed5aa0c619df3aa32d6663a2d2b2ec27ff Mon Sep 17 00:00:00 2001 From: Olivier Cazade Date: Wed, 24 Dec 2025 17:32:40 +0100 Subject: [PATCH 3/3] Fix compilation --- pkg/handler/loki.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/handler/loki.go b/pkg/handler/loki.go index 302a6c8de..0fb4a904a 100644 --- a/pkg/handler/loki.go +++ b/pkg/handler/loki.go @@ -235,7 +235,7 @@ func (h *Handlers) LokiMetrics() func(w http.ResponseWriter, r *http.Request) { writeError(w, http.StatusBadRequest, "Loki is disabled") return } - if h.Cfg.Loki.Status != nil { + if h.Cfg.Loki.Status != "" { writeError(w, http.StatusBadRequest, "Status URL endpoints are unavailable when using LokiStack operator. Status is provided via operator conditions.") return } @@ -258,7 +258,7 @@ func (h *Handlers) LokiBuildInfos() func(w http.ResponseWriter, r *http.Request) writeError(w, http.StatusBadRequest, "Loki is disabled") return } - if h.Cfg.Loki.Status != nil { + if h.Cfg.Loki.Status != "" { writeError(w, http.StatusBadRequest, "Loki status URL is not usable with Loki operator") return } @@ -276,7 +276,7 @@ func (h *Handlers) LokiBuildInfos() func(w http.ResponseWriter, r *http.Request) } func (h *Handlers) fetchLokiConfig(cl httpclient.Caller, output any) error { - if h.Cfg.Loki.Status != nil { + if h.Cfg.Loki.Status != "" { return fmt.Errorf("loki status url is not usable with Loki operator") }