mirror of
https://github.com/SigNoz/signoz.git
synced 2026-03-28 15:10:29 +00:00
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(factory): add service state tracking, AwaitHealthy, depends_on, and /healthz endpoint Add explicit lifecycle state tracking to factory.Registry services (starting/running/failed) modeled after Guava's ServiceManager. Services can declare dependencies via NewNamedService(..., dependsOn) which are validated for unknown refs and cycles at registry creation. AwaitHealthy blocks until all services reach running state. A /healthz endpoint is wired through signozapiserver returning 200/503 with per-service state. * feat(apiserver): move health endpoints to /api/v2/ and register readyz, livez * refactor(factory): use gonum for cycle detection, return error on cycles, fix test assertions Replace custom DFS cycle detection with gonum's topo.Sort + TarjanSCC. Dependency cycles now return an error from NewRegistry instead of being silently dropped. Use assert for final test assertions and require only for intermediate setup errors. * chore: go mod tidy * refactor(factory): decouple Handler from Registry, wire through Handlers struct Move Handler implementation to a private handler struct with NewHandler constructor instead of methods on *Registry. Route handler through the existing Handlers struct as RegistryHandler. Rename healthz.go to registry.go in signozapiserver. Fix handler_test.go for new param. * feat(factory): add ServiceWithHealthy interface, add Healthy to authz, user depends on authz Add ServiceWithHealthy interface embedding Service + Healthy. NamedService now delegates Healthy() to the underlying service, eliminating unwrapService. AuthZ interface requires Healthy(), implemented in both pkg and ee providers. User service declares dependency on authz via dependsOn. * test(integration): use /api/v2/healthz for readiness check, log 503 response body * fix(factory): replace fmt.Errorf with errors.Newf in tests to satisfy linter * feat: generate openapi spec * fix(integration): log errors at error level in healthz readiness check * test(integration): log and assert healthz response in test_setup * feat(user): implement ServiceWithHealthy for user service User service signals healthy after successful root user reconciliation or immediately when disabled. User Service interface now embeds factory.ServiceWithHealthy. * fix(factory): reflect service names as strings * fix(apiserver): document health 503 responses * feat: generate openapi spec
68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
package factory
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/SigNoz/signoz/pkg/http/render"
|
|
)
|
|
|
|
// Handler provides HTTP handler functions for service health checks.
|
|
type Handler interface {
|
|
// Readyz reports whether services are ready.
|
|
Readyz(http.ResponseWriter, *http.Request)
|
|
|
|
// Livez reports whether services are alive.
|
|
Livez(http.ResponseWriter, *http.Request)
|
|
|
|
// Healthz reports overall service health.
|
|
Healthz(http.ResponseWriter, *http.Request)
|
|
}
|
|
|
|
type handler struct {
|
|
registry *Registry
|
|
}
|
|
|
|
func NewHandler(registry *Registry) Handler {
|
|
return &handler{
|
|
registry: registry,
|
|
}
|
|
}
|
|
|
|
type Response struct {
|
|
Healthy bool `json:"healthy"`
|
|
Services map[State][]Name `json:"services"`
|
|
}
|
|
|
|
func (handler *handler) Healthz(rw http.ResponseWriter, req *http.Request) {
|
|
byState := handler.registry.ServicesByState()
|
|
healthy := handler.registry.IsHealthy()
|
|
|
|
statusCode := http.StatusOK
|
|
if !healthy {
|
|
statusCode = http.StatusServiceUnavailable
|
|
}
|
|
|
|
render.Success(rw, statusCode, Response{
|
|
Healthy: healthy,
|
|
Services: byState,
|
|
})
|
|
}
|
|
|
|
func (handler *handler) Readyz(rw http.ResponseWriter, req *http.Request) {
|
|
healthy := handler.registry.IsHealthy()
|
|
|
|
statusCode := http.StatusOK
|
|
if !healthy {
|
|
statusCode = http.StatusServiceUnavailable
|
|
}
|
|
|
|
render.Success(rw, statusCode, Response{
|
|
Healthy: healthy,
|
|
Services: handler.registry.ServicesByState(),
|
|
})
|
|
}
|
|
|
|
func (handler *handler) Livez(rw http.ResponseWriter, req *http.Request) {
|
|
render.Success(rw, http.StatusOK, nil)
|
|
}
|