mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-16 19:14:41 -07:00
Merge pull request #3326 from mfaizanse/health_endpoint_params
Added param options to /healthz endpoint
This commit is contained in:
@@ -875,8 +875,8 @@ func (s *Server) initEventTracking() {
|
||||
s.zReq(c, reply, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.Jsz(&optz.JSzOptions) })
|
||||
},
|
||||
"HEALTHZ": func(sub *subscription, c *client, _ *Account, subject, reply string, msg []byte) {
|
||||
optz := &EventFilterOptions{}
|
||||
s.zReq(c, reply, msg, optz, optz, func() (interface{}, error) { return s.healthz(), nil })
|
||||
optz := &HealthzEventOptions{}
|
||||
s.zReq(c, reply, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.healthz(&optz.HealthzOptions), nil })
|
||||
},
|
||||
}
|
||||
for name, req := range monSrvc {
|
||||
@@ -1433,6 +1433,12 @@ type JszEventOptions struct {
|
||||
EventFilterOptions
|
||||
}
|
||||
|
||||
// In the context of system events, HealthzEventOptions are options passed to Healthz
|
||||
type HealthzEventOptions struct {
|
||||
HealthzOptions
|
||||
EventFilterOptions
|
||||
}
|
||||
|
||||
// returns true if the request does NOT apply to this server and can be ignored.
|
||||
// DO NOT hold the server lock when
|
||||
func (s *Server) filterRequest(fOpts *EventFilterOptions) bool {
|
||||
|
||||
@@ -2170,6 +2170,8 @@ func TestServerEventsPingMonitorz(t *testing.T) {
|
||||
{"JSZ", nil, &JSzOptions{}, []string{"now", "disabled"}},
|
||||
|
||||
{"HEALTHZ", nil, &JSzOptions{}, []string{"status"}},
|
||||
{"HEALTHZ", &HealthzOptions{JSEnabled: true}, &JSzOptions{}, []string{"status"}},
|
||||
{"HEALTHZ", &HealthzOptions{JSServerOnly: true}, &JSzOptions{}, []string{"status"}},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
|
||||
@@ -1229,13 +1229,13 @@ func (c *cluster) waitOnServerHealthz(s *Server) {
|
||||
c.t.Helper()
|
||||
expires := time.Now().Add(30 * time.Second)
|
||||
for time.Now().Before(expires) {
|
||||
hs := s.healthz()
|
||||
hs := s.healthz(nil)
|
||||
if hs.Status == "ok" && hs.Error == _EMPTY_ {
|
||||
return
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
c.t.Fatalf("Expected server %q to eventually return healthz 'ok', but got %q", s, s.healthz().Error)
|
||||
c.t.Fatalf("Expected server %q to eventually return healthz 'ok', but got %q", s, s.healthz(nil).Error)
|
||||
}
|
||||
|
||||
func (c *cluster) waitOnServerCurrent(s *Server) {
|
||||
|
||||
@@ -17129,7 +17129,7 @@ func TestJetStreamWorkQueueSourceRestart(t *testing.T) {
|
||||
defer s.Shutdown()
|
||||
|
||||
checkFor(t, 10*time.Second, 200*time.Millisecond, func() error {
|
||||
hs := s.healthz()
|
||||
hs := s.healthz(nil)
|
||||
if hs.Status == "ok" && hs.Error == _EMPTY_ {
|
||||
return nil
|
||||
}
|
||||
@@ -17250,7 +17250,7 @@ func TestJetStreamWorkQueueSourceNamingRestart(t *testing.T) {
|
||||
defer s.Shutdown()
|
||||
|
||||
checkFor(t, 10*time.Second, 200*time.Millisecond, func() error {
|
||||
hs := s.healthz()
|
||||
hs := s.healthz(nil)
|
||||
if hs.Status == "ok" && hs.Error == _EMPTY_ {
|
||||
return nil
|
||||
}
|
||||
@@ -17268,6 +17268,22 @@ func TestJetStreamWorkQueueSourceNamingRestart(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestJetStreamDisabledHealthz(t *testing.T) {
|
||||
s := RunRandClientPortServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
if s.JetStreamEnabled() {
|
||||
t.Fatalf("Expected JetStream to be disabled")
|
||||
}
|
||||
|
||||
hs := s.healthz(&HealthzOptions{JSEnabled: true})
|
||||
if hs.Status == "unavailable" && hs.Error == NewJSNotEnabledError().Error() {
|
||||
return
|
||||
}
|
||||
|
||||
t.Fatalf("Expected healthz to return error if JetStream is disabled, got status: %s", hs.Status)
|
||||
}
|
||||
|
||||
func TestJetStreamPullMaxBytes(t *testing.T) {
|
||||
s := RunBasicJetStreamServer()
|
||||
if config := s.JetStreamConfig(); config != nil {
|
||||
|
||||
@@ -2603,6 +2603,12 @@ type JSzOptions struct {
|
||||
Limit int `json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
// HealthzOptions are options passed to Healthz
|
||||
type HealthzOptions struct {
|
||||
JSEnabled bool `json:"js-enabled,omitempty"`
|
||||
JSServerOnly bool `json:"js-server-only,omitempty"`
|
||||
}
|
||||
|
||||
type StreamDetail struct {
|
||||
Name string `json:"name"`
|
||||
Cluster *ClusterInfo `json:"cluster,omitempty"`
|
||||
@@ -2928,7 +2934,19 @@ func (s *Server) HandleHealthz(w http.ResponseWriter, r *http.Request) {
|
||||
s.httpReqStats[HealthzPath]++
|
||||
s.mu.Unlock()
|
||||
|
||||
hs := s.healthz()
|
||||
jsEnabled, err := decodeBool(w, r, "js-enabled")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
jsServerOnly, err := decodeBool(w, r, "js-server-only")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
hs := s.healthz(&HealthzOptions{
|
||||
JSEnabled: jsEnabled,
|
||||
JSServerOnly: jsServerOnly,
|
||||
})
|
||||
if hs.Error != _EMPTY_ {
|
||||
s.Warnf("Healthcheck failed: %q", hs.Error)
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
@@ -2942,9 +2960,14 @@ func (s *Server) HandleHealthz(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Generate health status.
|
||||
func (s *Server) healthz() *HealthStatus {
|
||||
func (s *Server) healthz(opts *HealthzOptions) *HealthStatus {
|
||||
var health = &HealthStatus{Status: "ok"}
|
||||
|
||||
// set option defaults
|
||||
if opts == nil {
|
||||
opts = &HealthzOptions{}
|
||||
}
|
||||
|
||||
if err := s.readyForConnections(time.Millisecond); err != nil {
|
||||
health.Status = "error"
|
||||
health.Error = err.Error()
|
||||
@@ -2954,6 +2977,12 @@ func (s *Server) healthz() *HealthStatus {
|
||||
// Check JetStream
|
||||
js := s.getJetStream()
|
||||
if js == nil {
|
||||
// If JetStream should be enabled then return error status.
|
||||
if opts.JSEnabled {
|
||||
health.Status = "unavailable"
|
||||
health.Error = NewJSNotEnabledError().Error()
|
||||
return health
|
||||
}
|
||||
return health
|
||||
}
|
||||
|
||||
@@ -2985,6 +3014,11 @@ func (s *Server) healthz() *HealthStatus {
|
||||
return health
|
||||
}
|
||||
|
||||
// If JSServerOnly is true, then do not check further accounts, streams and consumers.
|
||||
if opts.JSServerOnly {
|
||||
return health
|
||||
}
|
||||
|
||||
// Range across all accounts, the streams assigned to them, and the consumers.
|
||||
// If they are assigned to this server check their status.
|
||||
for acc, asa := range cc.streams {
|
||||
|
||||
Reference in New Issue
Block a user